• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
6 
7 #include <ctype.h>
8 
9 #include <map>
10 #include <string>
11 #include <vector>
12 
13 #include "ash/system/chromeos/network/network_connect.h"
14 #include "ash/system/chromeos/network/network_icon.h"
15 #include "base/basictypes.h"
16 #include "base/bind.h"
17 #include "base/bind_helpers.h"
18 #include "base/command_line.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/values.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/chromeos/login/users/user.h"
25 #include "chrome/browser/chromeos/login/users/user_manager.h"
26 #include "chrome/browser/chromeos/mobile_config.h"
27 #include "chrome/browser/chromeos/net/onc_utils.h"
28 #include "chrome/browser/chromeos/options/network_config_view.h"
29 #include "chrome/browser/chromeos/options/network_property_ui_data.h"
30 #include "chrome/browser/chromeos/settings/cros_settings.h"
31 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
32 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
33 #include "chrome/browser/chromeos/ui/mobile_config_ui.h"
34 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
35 #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
36 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h"
37 #include "chromeos/chromeos_switches.h"
38 #include "chromeos/network/device_state.h"
39 #include "chromeos/network/managed_network_configuration_handler.h"
40 #include "chromeos/network/network_configuration_handler.h"
41 #include "chromeos/network/network_connection_handler.h"
42 #include "chromeos/network/network_device_handler.h"
43 #include "chromeos/network/network_event_log.h"
44 #include "chromeos/network/network_ip_config.h"
45 #include "chromeos/network/network_profile.h"
46 #include "chromeos/network/network_profile_handler.h"
47 #include "chromeos/network/network_state.h"
48 #include "chromeos/network/network_state_handler.h"
49 #include "chromeos/network/network_ui_data.h"
50 #include "chromeos/network/network_util.h"
51 #include "components/onc/onc_constants.h"
52 #include "content/public/browser/notification_service.h"
53 #include "content/public/browser/user_metrics.h"
54 #include "content/public/browser/web_contents.h"
55 #include "content/public/browser/web_ui.h"
56 #include "grit/ash_resources.h"
57 #include "grit/locale_settings.h"
58 #include "grit/theme_resources.h"
59 #include "third_party/cros_system_api/dbus/service_constants.h"
60 #include "ui/base/l10n/l10n_util.h"
61 #include "ui/base/layout.h"
62 #include "ui/base/resource/resource_bundle.h"
63 #include "ui/base/webui/web_ui_util.h"
64 #include "ui/gfx/image/image_skia.h"
65 
66 namespace chromeos {
67 namespace options {
68 
69 namespace {
70 
71 // Keys for the network description dictionary passed to the web ui. Make sure
72 // to keep the strings in sync with what the JavaScript side uses.
73 const char kNetworkInfoKeyConnectable[] = "connectable";
74 const char kNetworkInfoKeyConnected[] = "connected";
75 const char kNetworkInfoKeyConnecting[] = "connecting";
76 const char kNetworkInfoKeyIconURL[] = "iconURL";
77 const char kNetworkInfoKeyNetworkName[] = "networkName";
78 const char kNetworkInfoKeyNetworkType[] = "networkType";
79 const char kNetworkInfoKeyServicePath[] = "servicePath";
80 const char kNetworkInfoKeyPolicyManaged[] = "policyManaged";
81 
82 // These are keys for getting IP information from the web ui.
83 const char kIpConfigAddress[] = "address";
84 const char kIpConfigPrefixLength[] = "prefixLength";
85 const char kIpConfigNetmask[] = "netmask";
86 const char kIpConfigGateway[] = "gateway";
87 const char kIpConfigNameServers[] = "nameServers";
88 const char kIpConfigAutoConfig[] = "ipAutoConfig";
89 const char kIpConfigWebProxyAutoDiscoveryUrl[] = "webProxyAutoDiscoveryUrl";
90 
91 // These are types of name server selections from the web ui.
92 const char kNameServerTypeAutomatic[] = "automatic";
93 const char kNameServerTypeGoogle[] = "google";
94 const char kNameServerTypeUser[] = "user";
95 
96 // These are dictionary names used to send data to the web ui.
97 const char kDictionaryIpConfig[] = "ipconfig";
98 const char kDictionaryStaticIp[] = "staticIP";
99 const char kDictionarySavedIp[] = "savedIP";
100 
101 // Google public name servers (DNS).
102 const char kGoogleNameServers[] = "8.8.4.4,8.8.8.8";
103 
104 // Functions we call in JavaScript.
105 const char kRefreshNetworkDataFunction[] =
106     "options.network.NetworkList.refreshNetworkData";
107 const char kSetDefaultNetworkIconsFunction[] =
108     "options.network.NetworkList.setDefaultNetworkIcons";
109 const char kShowDetailedInfoFunction[] =
110     "options.internet.DetailsInternetPage.showDetailedInfo";
111 const char kUpdateConnectionDataFunction[] =
112     "options.internet.DetailsInternetPage.updateConnectionData";
113 const char kUpdateCarrierFunction[] =
114     "options.internet.DetailsInternetPage.updateCarrier";
115 const char kUpdateLoggedInUserTypeFunction[] =
116     "options.network.NetworkList.updateLoggedInUserType";
117 const char kUpdateSecurityTabFunction[] =
118     "options.internet.DetailsInternetPage.updateSecurityTab";
119 
120 // These are used to register message handlers with JavaScript.
121 const char kBuyDataPlanMessage[] = "buyDataPlan";
122 const char kChangePinMessage[] = "changePin";
123 const char kDisableCellularMessage[] = "disableCellular";
124 const char kDisableWifiMessage[] = "disableWifi";
125 const char kDisableWimaxMessage[] = "disableWimax";
126 const char kEnableCellularMessage[] = "enableCellular";
127 const char kEnableWifiMessage[] = "enableWifi";
128 const char kEnableWimaxMessage[] = "enableWimax";
129 const char kNetworkCommandMessage[] = "networkCommand";
130 const char kRefreshNetworksMessage[] = "refreshNetworks";
131 const char kSetApnMessage[] = "setApn";
132 const char kSetAutoConnectMessage[] = "setAutoConnect";
133 const char kSetCarrierMessage[] = "setCarrier";
134 const char kSetIPConfigMessage[] = "setIPConfig";
135 const char kSetPreferNetworkMessage[] = "setPreferNetwork";
136 const char kSetServerHostname[] = "setServerHostname";
137 const char kSetSimCardLockMessage[] = "setSimCardLock";
138 const char kShowMorePlanInfoMessage[] = "showMorePlanInfo";
139 
140 // These are strings used to communicate with JavaScript.
141 const char kTagActivate[] = "activate";
142 const char kTagActivationState[] = "activationState";
143 const char kTagAddConnection[] = "add";
144 const char kTagApn[] = "apn";
145 const char kTagAutoConnect[] = "autoConnect";
146 const char kTagBssid[] = "bssid";
147 const char kTagCarrierSelectFlag[] = "showCarrierSelect";
148 const char kTagCarrierUrl[] = "carrierUrl";
149 const char kTagCellular[] = "cellular";
150 const char kTagCellularAvailable[] = "cellularAvailable";
151 const char kTagCellularEnabled[] = "cellularEnabled";
152 const char kTagCellularSupportsScan[] = "cellularSupportsScan";
153 const char kTagConfigure[] = "configure";
154 const char kTagConnect[] = "connect";
155 const char kTagConnected[] = "connected";
156 const char kTagConnecting[] = "connecting";
157 const char kTagConnectionState[] = "connectionState";
158 const char kTagControlledBy[] = "controlledBy";
159 const char kTagDeviceConnected[] = "deviceConnected";
160 const char kTagDisableConnectButton[] = "disableConnectButton";
161 const char kTagDisconnect[] = "disconnect";
162 const char kTagEncryption[] = "encryption";
163 const char kTagErrorState[] = "errorState";
164 const char kTagEsn[] = "esn";
165 const char kTagFirmwareRevision[] = "firmwareRevision";
166 const char kTagForget[] = "forget";
167 const char kTagFrequency[] = "frequency";
168 const char kTagGsm[] = "gsm";
169 const char kTagHardwareAddress[] = "hardwareAddress";
170 const char kTagHardwareRevision[] = "hardwareRevision";
171 const char kTagIdentity[] = "identity";
172 const char kTagIccid[] = "iccid";
173 const char kTagImei[] = "imei";
174 const char kTagImsi[] = "imsi";
175 const char kTagLanguage[] = "language";
176 const char kTagLastGoodApn[] = "lastGoodApn";
177 const char kTagLocalizedName[] = "localizedName";
178 const char kTagCellularManufacturer[] = "cellularManufacturer";
179 const char kTagMdn[] = "mdn";
180 const char kTagMeid[] = "meid";
181 const char kTagMin[] = "min";
182 const char kTagModelId[] = "modelId";
183 const char kTagName[] = "name";
184 const char kTagNameServersGoogle[] = "nameServersGoogle";
185 const char kTagNameServerType[] = "nameServerType";
186 const char kTagNetworkId[] = "networkId";
187 const char kTagNetworkName[] = "networkName";
188 const char kTagNetworkTechnology[] = "networkTechnology";
189 const char kTagOperatorCode[] = "operatorCode";
190 const char kTagOperatorName[] = "operatorName";
191 const char kTagOptions[] = "options";
192 const char kTagPassword[] = "password";
193 const char kTagPolicy[] = "policy";
194 const char kTagPreferred[] = "preferred";
195 const char kTagPrlVersion[] = "prlVersion";
196 const char kTagProviderType[] = "providerType";
197 const char kTagProviderApnList[] = "providerApnList";
198 const char kTagRecommended[] = "recommended";
199 const char kTagRecommendedValue[] = "recommendedValue";
200 const char kTagRemembered[] = "remembered";
201 const char kTagRememberedList[] = "rememberedList";
202 const char kTagRestrictedPool[] = "restrictedPool";
203 const char kTagRoamingState[] = "roamingState";
204 const char kTagServerHostname[] = "serverHostname";
205 const char kTagCarriers[] = "carriers";
206 const char kTagCurrentCarrierIndex[] = "currentCarrierIndex";
207 const char kTagServiceName[] = "serviceName";
208 const char kTagServicePath[] = "servicePath";
209 const char kTagShared[] = "shared";
210 const char kTagShowActivateButton[] = "showActivateButton";
211 const char kTagShowPreferred[] = "showPreferred";
212 const char kTagShowProxy[] = "showProxy";
213 const char kTagShowStaticIPConfig[] = "showStaticIPConfig";
214 const char kTagShowViewAccountButton[] = "showViewAccountButton";
215 const char kTagSimCardLockEnabled[] = "simCardLockEnabled";
216 const char kTagSsid[] = "ssid";
217 const char kTagStrength[] = "strength";
218 const char kTagSupportUrl[] = "supportUrl";
219 const char kTagTrue[] = "true";
220 const char kTagType[] = "type";
221 const char kTagUsername[] = "username";
222 const char kTagValue[] = "value";
223 const char kTagVpn[] = "vpn";
224 const char kTagVpnList[] = "vpnList";
225 const char kTagWifi[] = "wifi";
226 const char kTagWifiAvailable[] = "wifiAvailable";
227 const char kTagWifiEnabled[] = "wifiEnabled";
228 const char kTagWimaxAvailable[] = "wimaxAvailable";
229 const char kTagWimaxEnabled[] = "wimaxEnabled";
230 const char kTagWiredList[] = "wiredList";
231 const char kTagWirelessList[] = "wirelessList";
232 const char kTagLoggedInUserNone[] = "none";
233 const char kTagLoggedInUserRegular[] = "regular";
234 const char kTagLoggedInUserOwner[] = "owner";
235 const char kTagLoggedInUserGuest[] = "guest";
236 const char kTagLoggedInUserRetailMode[] = "retail-mode";
237 const char kTagLoggedInUserPublicAccount[] = "public-account";
238 const char kTagLoggedInUserLocallyManaged[] = "locally-managed";
239 const char kTagLoggedInUserKioskApp[] = "kiosk-app";
240 
241 const int kPreferredPriority = 1;
242 
ShillError(const std::string & function,const std::string & error_name,scoped_ptr<base::DictionaryValue> error_data)243 void ShillError(const std::string& function,
244                 const std::string& error_name,
245                 scoped_ptr<base::DictionaryValue> error_data) {
246   // UpdateConnectionData may send requests for stale services; ignore
247   // these errors.
248   if (function == "UpdateConnectionData" &&
249       error_name == network_handler::kDBusFailedError)
250     return;
251   NET_LOG_ERROR("Shill Error from InternetOptionsHandler: " + error_name,
252                 function);
253 }
254 
GetNetworkState(const std::string & service_path)255 const NetworkState* GetNetworkState(const std::string& service_path) {
256   return NetworkHandler::Get()->network_state_handler()->
257       GetNetworkState(service_path);
258 }
259 
SetNetworkProperty(const std::string & service_path,const std::string & property,base::Value * value)260 void SetNetworkProperty(const std::string& service_path,
261                         const std::string& property,
262                         base::Value* value) {
263   NET_LOG_EVENT("SetNetworkProperty: " + property, service_path);
264   base::DictionaryValue properties;
265   properties.SetWithoutPathExpansion(property, value);
266   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
267       service_path, properties,
268       base::Bind(&base::DoNothing),
269       base::Bind(&ShillError, "SetNetworkProperty"));
270 }
271 
LoggedInUserTypeToJSString(LoginState::LoggedInUserType type)272 std::string LoggedInUserTypeToJSString(LoginState::LoggedInUserType type) {
273   switch (type) {
274     case LoginState::LOGGED_IN_USER_NONE:
275       return kTagLoggedInUserNone;
276     case LoginState::LOGGED_IN_USER_REGULAR:
277       return kTagLoggedInUserRegular;
278     case LoginState::LOGGED_IN_USER_OWNER:
279       return kTagLoggedInUserOwner;
280     case LoginState::LOGGED_IN_USER_GUEST:
281       return kTagLoggedInUserGuest;
282     case LoginState::LOGGED_IN_USER_RETAIL_MODE:
283       return kTagLoggedInUserRetailMode;
284     case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT:
285       return kTagLoggedInUserPublicAccount;
286     case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED:
287       return kTagLoggedInUserLocallyManaged;
288     case LoginState::LOGGED_IN_USER_KIOSK_APP:
289       return kTagLoggedInUserKioskApp;
290   }
291   NOTREACHED();
292   return std::string();
293 }
294 
SetCommonNetworkInfo(const NetworkState * state,const std::string & icon_url,base::DictionaryValue * network_info)295 void SetCommonNetworkInfo(const NetworkState* state,
296                           const std::string& icon_url,
297                           base::DictionaryValue* network_info) {
298   network_info->SetString(kNetworkInfoKeyIconURL, icon_url);
299 
300   std::string name = state->name();
301   if (state->Matches(NetworkTypePattern::Ethernet())) {
302     name = internet_options_strings::NetworkDeviceTypeString(
303         shill::kTypeEthernet);
304   }
305   network_info->SetString(kNetworkInfoKeyNetworkName, name);
306   network_info->SetString(kNetworkInfoKeyNetworkType, state->type());
307   network_info->SetString(kNetworkInfoKeyServicePath, state->path());
308 }
309 
310 // Builds a dictionary with network information and an icon used for the
311 // NetworkList on the settings page. Ownership of the returned pointer is
312 // transferred to the caller.
BuildNetworkDictionary(const NetworkState * network,float icon_scale_factor,const PrefService * profile_prefs)313 base::DictionaryValue* BuildNetworkDictionary(
314     const NetworkState* network,
315     float icon_scale_factor,
316     const PrefService* profile_prefs) {
317   scoped_ptr<base::DictionaryValue> network_info(new base::DictionaryValue());
318   if (network->visible()) {
319     network_info->SetBoolean(kNetworkInfoKeyConnectable,
320                              network->connectable());
321     network_info->SetBoolean(kNetworkInfoKeyConnected,
322                              network->IsConnectedState());
323     network_info->SetBoolean(kNetworkInfoKeyConnecting,
324                              network->IsConnectingState());
325   } else {
326     network_info->SetBoolean(kNetworkInfoKeyConnectable, false);
327     network_info->SetBoolean(kNetworkInfoKeyConnected, false);
328     network_info->SetBoolean(kNetworkInfoKeyConnecting, false);
329   }
330   bool has_policy = onc::HasPolicyForNetwork(
331       profile_prefs, g_browser_process->local_state(), *network);
332   network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, has_policy);
333 
334   std::string icon_url = ash::network_icon::GetImageUrlForNetwork(
335       network, ash::network_icon::ICON_TYPE_LIST, icon_scale_factor);
336   SetCommonNetworkInfo(network, icon_url, network_info.get());
337   return network_info.release();
338 }
339 
340 // Pulls IP information out of a shill service properties dictionary. If
341 // |static_ip| is true, then it fetches "StaticIP.*" properties. If not, then it
342 // fetches "SavedIP.*" properties. Caller must take ownership of returned
343 // dictionary.  If non-NULL, |ip_parameters_set| returns a count of the number
344 // of IP routing parameters that get set.
BuildIPInfoDictionary(const base::DictionaryValue & shill_properties,bool static_ip,int * routing_parameters_set)345 base::DictionaryValue* BuildIPInfoDictionary(
346     const base::DictionaryValue& shill_properties,
347     bool static_ip,
348     int* routing_parameters_set) {
349   std::string address_key;
350   std::string prefix_len_key;
351   std::string gateway_key;
352   std::string name_servers_key;
353   if (static_ip) {
354     address_key = shill::kStaticIPAddressProperty;
355     prefix_len_key = shill::kStaticIPPrefixlenProperty;
356     gateway_key = shill::kStaticIPGatewayProperty;
357     name_servers_key = shill::kStaticIPNameServersProperty;
358   } else {
359     address_key = shill::kSavedIPAddressProperty;
360     prefix_len_key = shill::kSavedIPPrefixlenProperty;
361     gateway_key = shill::kSavedIPGatewayProperty;
362     name_servers_key = shill::kSavedIPNameServersProperty;
363   }
364 
365   scoped_ptr<base::DictionaryValue> ip_info_dict(new base::DictionaryValue);
366   std::string address;
367   int routing_parameters = 0;
368   if (shill_properties.GetStringWithoutPathExpansion(address_key, &address)) {
369     ip_info_dict->SetString(kIpConfigAddress, address);
370     VLOG(2) << "Found " << address_key << ": " << address;
371     routing_parameters++;
372   }
373   int prefix_len = -1;
374   if (shill_properties.GetIntegerWithoutPathExpansion(
375       prefix_len_key, &prefix_len)) {
376     ip_info_dict->SetInteger(kIpConfigPrefixLength, prefix_len);
377     std::string netmask = network_util::PrefixLengthToNetmask(prefix_len);
378     ip_info_dict->SetString(kIpConfigNetmask, netmask);
379     VLOG(2) << "Found " << prefix_len_key << ": "
380             <<  prefix_len << " (" << netmask << ")";
381     routing_parameters++;
382   }
383   std::string gateway;
384   if (shill_properties.GetStringWithoutPathExpansion(gateway_key, &gateway)) {
385     ip_info_dict->SetString(kIpConfigGateway, gateway);
386     VLOG(2) << "Found " << gateway_key << ": " << gateway;
387     routing_parameters++;
388   }
389   if (routing_parameters_set)
390     *routing_parameters_set = routing_parameters;
391 
392   std::string name_servers;
393   if (shill_properties.GetStringWithoutPathExpansion(
394       name_servers_key, &name_servers)) {
395     ip_info_dict->SetString(kIpConfigNameServers, name_servers);
396     VLOG(2) << "Found " << name_servers_key << ": " << name_servers;
397   }
398 
399   return ip_info_dict.release();
400 }
401 
CanForgetNetworkType(const std::string & type)402 bool CanForgetNetworkType(const std::string& type) {
403   return type == shill::kTypeWifi ||
404          type == shill::kTypeWimax ||
405          type == shill::kTypeVPN;
406 }
407 
CanAddNetworkType(const std::string & type)408 bool CanAddNetworkType(const std::string& type) {
409   return type == shill::kTypeWifi ||
410          type == shill::kTypeVPN ||
411          type == shill::kTypeCellular;
412 }
413 
414 // Decorate dictionary |value_dict| with policy information from |ui_data|.
DecorateValueDictionary(const NetworkPropertyUIData & ui_data,const base::Value & value,base::DictionaryValue * value_dict)415 void DecorateValueDictionary(const NetworkPropertyUIData& ui_data,
416                              const base::Value& value,
417                              base::DictionaryValue* value_dict) {
418   const base::Value* recommended_value = ui_data.default_value();
419   if (ui_data.IsManaged())
420     value_dict->SetString(kTagControlledBy, kTagPolicy);
421   else if (recommended_value && recommended_value->Equals(&value))
422     value_dict->SetString(kTagControlledBy, kTagRecommended);
423 
424   if (recommended_value)
425     value_dict->Set(kTagRecommendedValue, recommended_value->DeepCopy());
426 }
427 
428 // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does and
429 // store it under |key| in |settings|. Takes ownership of |value|.
SetValueDictionary(base::DictionaryValue * settings,const char * key,base::Value * value,const NetworkPropertyUIData & ui_data)430 void SetValueDictionary(base::DictionaryValue* settings,
431                         const char* key,
432                         base::Value* value,
433                         const NetworkPropertyUIData& ui_data) {
434   base::DictionaryValue* dict = new base::DictionaryValue();
435   // DictionaryValue::Set() takes ownership of |value|.
436   dict->Set(kTagValue, value);
437   settings->Set(key, dict);
438   DecorateValueDictionary(ui_data, *value, dict);
439 }
440 
441 // Creates a decorated dictionary like SetValueDictionary does, but extended for
442 // the Autoconnect property, which respects additionally global network policy.
SetAutoconnectValueDictionary(bool network_is_private,::onc::ONCSource onc_source,bool current_autoconnect,const NetworkPropertyUIData & ui_data,base::DictionaryValue * settings)443 void SetAutoconnectValueDictionary(bool network_is_private,
444                                    ::onc::ONCSource onc_source,
445                                    bool current_autoconnect,
446                                    const NetworkPropertyUIData& ui_data,
447                                    base::DictionaryValue* settings) {
448   base::DictionaryValue* dict = new base::DictionaryValue();
449   base::Value* value = new base::FundamentalValue(current_autoconnect);
450   // DictionaryValue::Set() takes ownership of |value|.
451   dict->Set(kTagValue, value);
452   settings->Set(kTagAutoConnect, dict);
453   if (onc_source != ::onc::ONC_SOURCE_USER_POLICY &&
454       onc_source != ::onc::ONC_SOURCE_DEVICE_POLICY) {
455     // Autoconnect can be controlled by the GlobalNetworkConfiguration of the
456     // ONC policy.
457     bool only_policy_autoconnect =
458         onc::PolicyAllowsOnlyPolicyNetworksToAutoconnect(network_is_private);
459     if (only_policy_autoconnect) {
460       dict->SetString(kTagControlledBy, kTagPolicy);
461       return;
462     }
463   }
464   DecorateValueDictionary(ui_data, *value, dict);
465 }
466 
CopyStringFromDictionary(const base::DictionaryValue & source,const std::string & src_key,const std::string & dest_key,base::DictionaryValue * dest)467 std::string CopyStringFromDictionary(const base::DictionaryValue& source,
468                                      const std::string& src_key,
469                                      const std::string& dest_key,
470                                      base::DictionaryValue* dest) {
471   std::string string_value;
472   if (source.GetStringWithoutPathExpansion(src_key, &string_value))
473     dest->SetStringWithoutPathExpansion(dest_key, string_value);
474   return string_value;
475 }
476 
CopyIntegerFromDictionary(const base::DictionaryValue & source,const std::string & src_key,const std::string & dest_key,bool as_string,base::DictionaryValue * dest)477 void CopyIntegerFromDictionary(const base::DictionaryValue& source,
478                                const std::string& src_key,
479                                const std::string& dest_key,
480                                bool as_string,
481                                base::DictionaryValue* dest) {
482   int int_value;
483   if (!source.GetIntegerWithoutPathExpansion(src_key, &int_value))
484     return;
485   if (as_string) {
486     dest->SetStringWithoutPathExpansion(dest_key, base::IntToString(int_value));
487   } else {
488     dest->SetIntegerWithoutPathExpansion(dest_key, int_value);
489   }
490 }
491 
492 // Fills |dictionary| with the configuration details of |vpn|. |onc| is required
493 // for augmenting the policy-managed information.
PopulateVPNDetails(const NetworkState * vpn,const base::DictionaryValue & shill_properties,base::DictionaryValue * dictionary)494 void PopulateVPNDetails(const NetworkState* vpn,
495                         const base::DictionaryValue& shill_properties,
496                         base::DictionaryValue* dictionary) {
497   // Name and Remembered are set in PopulateConnectionDetails().
498   // Provider properties are stored in the "Provider" dictionary.
499   const base::DictionaryValue* provider_properties = NULL;
500   if (!shill_properties.GetDictionaryWithoutPathExpansion(
501           shill::kProviderProperty, &provider_properties)) {
502     LOG(ERROR) << "No provider properties for VPN: " << vpn->path();
503     return;
504   }
505   std::string provider_type;
506   provider_properties->GetStringWithoutPathExpansion(
507       shill::kTypeProperty, &provider_type);
508   dictionary->SetString(kTagProviderType,
509                         internet_options_strings::ProviderTypeString(
510                             provider_type,
511                             *provider_properties));
512 
513   std::string username;
514   if (provider_type == shill::kProviderOpenVpn) {
515     provider_properties->GetStringWithoutPathExpansion(
516         shill::kOpenVPNUserProperty, &username);
517   } else {
518     provider_properties->GetStringWithoutPathExpansion(
519         shill::kL2tpIpsecUserProperty, &username);
520   }
521   dictionary->SetString(kTagUsername, username);
522 
523   ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
524   const base::DictionaryValue* onc =
525       onc::FindPolicyForActiveUser(vpn->guid(), &onc_source);
526 
527   NetworkPropertyUIData hostname_ui_data;
528   hostname_ui_data.ParseOncProperty(
529       onc_source,
530       onc,
531       ::onc::network_config::VpnProperty(::onc::vpn::kHost));
532   std::string provider_host;
533   provider_properties->GetStringWithoutPathExpansion(
534       shill::kHostProperty, &provider_host);
535   SetValueDictionary(dictionary, kTagServerHostname,
536                      new base::StringValue(provider_host),
537                      hostname_ui_data);
538 
539   // Disable 'Connect' for VPN unless connected to a non-VPN network.
540   const NetworkState* connected_network =
541       NetworkHandler::Get()->network_state_handler()->ConnectedNetworkByType(
542           NetworkTypePattern::NonVirtual());
543   dictionary->SetBoolean(kTagDisableConnectButton, !connected_network);
544 }
545 
546 // Given a list of supported carrier's by the device, return the index of
547 // the carrier the device is currently using.
FindCurrentCarrierIndex(const base::ListValue * carriers,const DeviceState * device)548 int FindCurrentCarrierIndex(const base::ListValue* carriers,
549                             const DeviceState* device) {
550   DCHECK(carriers);
551   DCHECK(device);
552   bool gsm = (device->technology_family() == shill::kTechnologyFamilyGsm);
553   int index = 0;
554   for (base::ListValue::const_iterator it = carriers->begin();
555        it != carriers->end(); ++it, ++index) {
556     std::string value;
557     if (!(*it)->GetAsString(&value))
558       continue;
559     // For GSM devices the device name will be empty, so simply select
560     // the Generic UMTS carrier option if present.
561     if (gsm && (value == shill::kCarrierGenericUMTS))
562       return index;
563     // For other carriers, the service name will match the carrier name.
564     if (value == device->carrier())
565       return index;
566   }
567   return -1;
568 }
569 
PopulateWifiDetails(const NetworkState * wifi,const base::DictionaryValue & shill_properties,base::DictionaryValue * dictionary)570 void PopulateWifiDetails(const NetworkState* wifi,
571                          const base::DictionaryValue& shill_properties,
572                          base::DictionaryValue* dictionary) {
573   dictionary->SetString(kTagSsid, wifi->name());
574   dictionary->SetInteger(kTagStrength, wifi->signal_strength());
575   dictionary->SetString(kTagEncryption,
576                         internet_options_strings::EncryptionString(
577                             wifi->security(), wifi->eap_method()));
578   CopyStringFromDictionary(
579       shill_properties, shill::kWifiBSsid, kTagBssid, dictionary);
580   CopyIntegerFromDictionary(shill_properties,
581                             shill::kWifiFrequency,
582                             kTagFrequency,
583                             false,
584                             dictionary);
585 }
586 
PopulateWimaxDetails(const NetworkState * wimax,const base::DictionaryValue & shill_properties,base::DictionaryValue * dictionary)587 void PopulateWimaxDetails(const NetworkState* wimax,
588                           const base::DictionaryValue& shill_properties,
589                           base::DictionaryValue* dictionary) {
590   dictionary->SetInteger(kTagStrength, wimax->signal_strength());
591   CopyStringFromDictionary(
592       shill_properties, shill::kEapIdentityProperty, kTagIdentity, dictionary);
593 }
594 
CreateDictionaryFromCellularApn(const base::DictionaryValue * apn,base::DictionaryValue * dictionary)595 void CreateDictionaryFromCellularApn(const base::DictionaryValue* apn,
596                                      base::DictionaryValue* dictionary) {
597   CopyStringFromDictionary(*apn, shill::kApnProperty, kTagApn, dictionary);
598   CopyStringFromDictionary(
599       *apn, shill::kApnNetworkIdProperty, kTagNetworkId, dictionary);
600   CopyStringFromDictionary(
601       *apn, shill::kApnUsernameProperty, kTagUsername, dictionary);
602   CopyStringFromDictionary(
603       *apn, shill::kApnPasswordProperty, kTagPassword, dictionary);
604   CopyStringFromDictionary(*apn, shill::kApnNameProperty, kTagName, dictionary);
605   CopyStringFromDictionary(
606       *apn, shill::kApnLocalizedNameProperty, kTagLocalizedName, dictionary);
607   CopyStringFromDictionary(
608       *apn, shill::kApnLanguageProperty, kTagLanguage, dictionary);
609 }
610 
PopulateCellularDetails(const NetworkState * cellular,const base::DictionaryValue & shill_properties,base::DictionaryValue * dictionary)611 void PopulateCellularDetails(const NetworkState* cellular,
612                              const base::DictionaryValue& shill_properties,
613                              base::DictionaryValue* dictionary) {
614   dictionary->SetBoolean(kTagCarrierSelectFlag,
615                          CommandLine::ForCurrentProcess()->HasSwitch(
616                              chromeos::switches::kEnableCarrierSwitching));
617   // Cellular network / connection settings.
618   dictionary->SetString(kTagNetworkTechnology, cellular->network_technology());
619   dictionary->SetString(kTagActivationState,
620                         internet_options_strings::ActivationStateString(
621                             cellular->activation_state()));
622   dictionary->SetString(kTagRoamingState,
623                         internet_options_strings::RoamingStateString(
624                             cellular->roaming()));
625   dictionary->SetString(
626       kTagRestrictedPool,
627       internet_options_strings::RestrictedStateString(
628           cellular->connection_state()));
629 
630   const base::DictionaryValue* serving_operator = NULL;
631   if (shill_properties.GetDictionaryWithoutPathExpansion(
632           shill::kServingOperatorProperty, &serving_operator)) {
633     CopyStringFromDictionary(*serving_operator,
634                              shill::kOperatorNameKey,
635                              kTagOperatorName,
636                              dictionary);
637     CopyStringFromDictionary(*serving_operator,
638                              shill::kOperatorCodeKey,
639                              kTagOperatorCode,
640                              dictionary);
641   }
642 
643   const base::DictionaryValue* olp = NULL;
644   if (shill_properties.GetDictionaryWithoutPathExpansion(
645           shill::kPaymentPortalProperty, &olp)) {
646     std::string url;
647     olp->GetStringWithoutPathExpansion(shill::kPaymentPortalURL, &url);
648     dictionary->SetString(kTagSupportUrl, url);
649   }
650 
651   base::DictionaryValue* apn = new base::DictionaryValue;
652   const base::DictionaryValue* source_apn = NULL;
653   if (shill_properties.GetDictionaryWithoutPathExpansion(
654           shill::kCellularApnProperty, &source_apn)) {
655     CreateDictionaryFromCellularApn(source_apn, apn);
656   }
657   dictionary->Set(kTagApn, apn);
658 
659   base::DictionaryValue* last_good_apn = new base::DictionaryValue;
660   if (shill_properties.GetDictionaryWithoutPathExpansion(
661           shill::kCellularLastGoodApnProperty, &source_apn)) {
662     CreateDictionaryFromCellularApn(source_apn, last_good_apn);
663   }
664   dictionary->Set(kTagLastGoodApn, last_good_apn);
665 
666   // These default to empty and are only set if device != NULL.
667   std::string carrier_id;
668   std::string mdn;
669 
670   // Device settings.
671   const DeviceState* device =
672       NetworkHandler::Get()->network_state_handler()->GetDeviceState(
673           cellular->device_path());
674   if (device) {
675     // TODO(stevenjb): Add NetworkDeviceHandler::GetProperties() and use that
676     // to retrieve the complete dictionary of device properties, instead of
677     // caching them (will be done for the new UI).
678     const base::DictionaryValue& device_properties = device->properties();
679     const NetworkPropertyUIData cellular_property_ui_data(
680         cellular->ui_data().onc_source());
681     CopyStringFromDictionary(device_properties,
682                              shill::kManufacturerProperty,
683                              kTagCellularManufacturer,
684                              dictionary);
685     CopyStringFromDictionary(
686         device_properties, shill::kModelIDProperty, kTagModelId, dictionary);
687     CopyStringFromDictionary(device_properties,
688                              shill::kFirmwareRevisionProperty,
689                              kTagFirmwareRevision,
690                              dictionary);
691     CopyStringFromDictionary(device_properties,
692                              shill::kHardwareRevisionProperty,
693                              kTagHardwareRevision,
694                              dictionary);
695     CopyIntegerFromDictionary(device_properties,
696                               shill::kPRLVersionProperty,
697                               kTagPrlVersion,
698                               true,
699                               dictionary);
700     CopyStringFromDictionary(
701         device_properties, shill::kMeidProperty, kTagMeid, dictionary);
702     CopyStringFromDictionary(
703         device_properties, shill::kIccidProperty, kTagIccid, dictionary);
704     CopyStringFromDictionary(
705         device_properties, shill::kImeiProperty, kTagImei, dictionary);
706     mdn = CopyStringFromDictionary(
707         device_properties, shill::kMdnProperty, kTagMdn, dictionary);
708     CopyStringFromDictionary(
709         device_properties, shill::kImsiProperty, kTagImsi, dictionary);
710     CopyStringFromDictionary(
711         device_properties, shill::kEsnProperty, kTagEsn, dictionary);
712     CopyStringFromDictionary(
713         device_properties, shill::kMinProperty, kTagMin, dictionary);
714     std::string family;
715     device_properties.GetStringWithoutPathExpansion(
716         shill::kTechnologyFamilyProperty, &family);
717     dictionary->SetBoolean(kTagGsm, family == shill::kNetworkTechnologyGsm);
718 
719     SetValueDictionary(dictionary,
720                        kTagSimCardLockEnabled,
721                        new base::FundamentalValue(device->sim_lock_enabled()),
722                        cellular_property_ui_data);
723 
724     carrier_id = device->home_provider_id();
725 
726     MobileConfig* config = MobileConfig::GetInstance();
727     if (config->IsReady()) {
728       const MobileConfig::Carrier* carrier = config->GetCarrier(carrier_id);
729       if (carrier && !carrier->top_up_url().empty())
730         dictionary->SetString(kTagCarrierUrl, carrier->top_up_url());
731     }
732 
733     base::ListValue* apn_list_value = new base::ListValue();
734     const base::ListValue* apn_list;
735     if (device_properties.GetListWithoutPathExpansion(
736             shill::kCellularApnListProperty, &apn_list)) {
737       for (base::ListValue::const_iterator iter = apn_list->begin();
738            iter != apn_list->end();
739            ++iter) {
740         const base::DictionaryValue* dict;
741         if ((*iter)->GetAsDictionary(&dict)) {
742           base::DictionaryValue* apn = new base::DictionaryValue;
743           CreateDictionaryFromCellularApn(dict, apn);
744           apn_list_value->Append(apn);
745         }
746       }
747     }
748     SetValueDictionary(dictionary,
749                        kTagProviderApnList,
750                        apn_list_value,
751                        cellular_property_ui_data);
752     if (CommandLine::ForCurrentProcess()->HasSwitch(
753             chromeos::switches::kEnableCarrierSwitching)) {
754       const base::ListValue* supported_carriers;
755       if (device_properties.GetListWithoutPathExpansion(
756               shill::kSupportedCarriersProperty, &supported_carriers)) {
757         dictionary->Set(kTagCarriers, supported_carriers->DeepCopy());
758         dictionary->SetInteger(
759             kTagCurrentCarrierIndex,
760             FindCurrentCarrierIndex(supported_carriers, device));
761       } else {
762         // In case of any error, set the current carrier tag to -1 indicating
763         // to the JS code to fallback to a single carrier.
764         dictionary->SetInteger(kTagCurrentCarrierIndex, -1);
765       }
766     }
767   }
768 
769   // Set Cellular Buttons Visibility
770   dictionary->SetBoolean(
771       kTagDisableConnectButton,
772       cellular->activation_state() == shill::kActivationStateActivating ||
773           cellular->IsConnectingState());
774 
775   // Don't show any account management related buttons if the activation
776   // state is unknown or no payment portal URL is available.
777   std::string support_url;
778   if (cellular->activation_state() == shill::kActivationStateUnknown ||
779       !dictionary->GetString(kTagSupportUrl, &support_url) ||
780       support_url.empty()) {
781     VLOG(2) << "No support URL is available. Don't display buttons.";
782     return;
783   }
784 
785   if (cellular->activation_state() != shill::kActivationStateActivating &&
786       cellular->activation_state() != shill::kActivationStateActivated) {
787     dictionary->SetBoolean(kTagShowActivateButton, true);
788   } else {
789     bool may_show_portal_button = false;
790 
791     // If an online payment URL was provided by shill, then this means that the
792     // "View Account" button should be shown for the current carrier.
793     if (olp) {
794       std::string url;
795       olp->GetStringWithoutPathExpansion(shill::kPaymentPortalURL, &url);
796       may_show_portal_button = !url.empty();
797     }
798     // If no online payment URL was provided by shill, fall back to
799     // MobileConfig to determine if the "View Account" should be shown.
800     if (!may_show_portal_button && MobileConfig::GetInstance()->IsReady()) {
801       const MobileConfig::Carrier* carrier =
802           MobileConfig::GetInstance()->GetCarrier(carrier_id);
803       may_show_portal_button = carrier && carrier->show_portal_button();
804     }
805     if (may_show_portal_button) {
806       // The button should be shown for a LTE network even when the LTE network
807       // is not connected, but CrOS is online. This is done to enable users to
808       // update their plan even if they are out of credits.
809       // The button should not be shown when the device's mdn is not set,
810       // because the network's proper portal url cannot be generated without it
811       const NetworkState* default_network =
812           NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
813       const std::string& technology = cellular->network_technology();
814       bool force_show_view_account_button =
815           (technology == shill::kNetworkTechnologyLte ||
816            technology == shill::kNetworkTechnologyLteAdvanced) &&
817           default_network && !mdn.empty();
818 
819       // The button will trigger ShowMorePlanInfoCallback() which will open
820       // carrier specific portal.
821       if (cellular->IsConnectedState() || force_show_view_account_button)
822         dictionary->SetBoolean(kTagShowViewAccountButton, true);
823     }
824   }
825 }
826 
PopulateConnectionDetails(const NetworkState * network,const base::DictionaryValue & shill_properties,base::DictionaryValue * dictionary)827 void PopulateConnectionDetails(const NetworkState* network,
828                                const base::DictionaryValue& shill_properties,
829                                base::DictionaryValue* dictionary) {
830   dictionary->SetString(kNetworkInfoKeyServicePath, network->path());
831   dictionary->SetString(kTagServiceName, network->name());
832   dictionary->SetBoolean(kTagConnecting, network->IsConnectingState());
833   dictionary->SetBoolean(kTagConnected, network->IsConnectedState());
834   dictionary->SetString(kTagConnectionState,
835                         internet_options_strings::ConnectionStateString(
836                             network->connection_state()));
837   dictionary->SetString(kTagNetworkName, network->name());
838   dictionary->SetString(
839       kTagErrorState,
840       ash::network_connect::ErrorString(network->error(), network->path()));
841 
842   dictionary->SetBoolean(kTagRemembered, !network->profile_path().empty());
843   bool shared = !network->IsPrivate();
844   dictionary->SetBoolean(kTagShared, shared);
845 
846   const std::string& type = network->type();
847   const NetworkState* connected_network =
848       NetworkHandler::Get()->network_state_handler()->ConnectedNetworkByType(
849           NetworkTypePattern::Primitive(type));
850 
851   dictionary->SetBoolean(kTagDeviceConnected, connected_network != NULL);
852 
853   if (type == shill::kTypeWifi)
854     PopulateWifiDetails(network, shill_properties, dictionary);
855   else if (type == shill::kTypeWimax)
856     PopulateWimaxDetails(network, shill_properties, dictionary);
857   else if (type == shill::kTypeCellular)
858     PopulateCellularDetails(network, shill_properties, dictionary);
859   else if (type == shill::kTypeVPN)
860     PopulateVPNDetails(network, shill_properties, dictionary);
861 }
862 
863 // Helper methods for SetIPConfigProperties
AppendPropertyKeyIfPresent(const std::string & key,const base::DictionaryValue & old_properties,std::vector<std::string> * property_keys)864 bool AppendPropertyKeyIfPresent(const std::string& key,
865                                 const base::DictionaryValue& old_properties,
866                                 std::vector<std::string>* property_keys) {
867   if (old_properties.HasKey(key)) {
868     property_keys->push_back(key);
869     return true;
870   }
871   return false;
872 }
873 
AddStringPropertyIfChanged(const std::string & key,const std::string & new_value,const base::DictionaryValue & old_properties,base::DictionaryValue * new_properties)874 bool AddStringPropertyIfChanged(const std::string& key,
875                                 const std::string& new_value,
876                                 const base::DictionaryValue& old_properties,
877                                 base::DictionaryValue* new_properties) {
878   std::string old_value;
879   if (!old_properties.GetStringWithoutPathExpansion(key, &old_value) ||
880       new_value != old_value) {
881     new_properties->SetStringWithoutPathExpansion(key, new_value);
882     return true;
883   }
884   return false;
885 }
886 
AddIntegerPropertyIfChanged(const std::string & key,int new_value,const base::DictionaryValue & old_properties,base::DictionaryValue * new_properties)887 bool AddIntegerPropertyIfChanged(const std::string& key,
888                                  int new_value,
889                                  const base::DictionaryValue& old_properties,
890                                  base::DictionaryValue* new_properties) {
891   int old_value;
892   if (!old_properties.GetIntegerWithoutPathExpansion(key, &old_value) ||
893       new_value != old_value) {
894     new_properties->SetIntegerWithoutPathExpansion(key, new_value);
895     return true;
896   }
897   return false;
898 }
899 
RequestReconnect(const std::string & service_path,gfx::NativeWindow owning_window)900 void RequestReconnect(const std::string& service_path,
901                       gfx::NativeWindow owning_window) {
902   NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
903       service_path,
904       base::Bind(&ash::network_connect::ConnectToNetwork,
905                  service_path, owning_window),
906       base::Bind(&ShillError, "RequestReconnect"));
907 }
908 
909 }  // namespace
910 
InternetOptionsHandler()911 InternetOptionsHandler::InternetOptionsHandler()
912     : weak_factory_(this) {
913   registrar_.Add(this, chrome::NOTIFICATION_REQUIRE_PIN_SETTING_CHANGE_ENDED,
914                  content::NotificationService::AllSources());
915   registrar_.Add(this, chrome::NOTIFICATION_ENTER_PIN_ENDED,
916                  content::NotificationService::AllSources());
917   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
918   LoginState::Get()->AddObserver(this);
919 }
920 
~InternetOptionsHandler()921 InternetOptionsHandler::~InternetOptionsHandler() {
922   if (NetworkHandler::IsInitialized()) {
923     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
924         this, FROM_HERE);
925   }
926   if (LoginState::Get()->IsInitialized())
927     LoginState::Get()->RemoveObserver(this);
928 }
929 
GetLocalizedValues(base::DictionaryValue * localized_strings)930 void InternetOptionsHandler::GetLocalizedValues(
931     base::DictionaryValue* localized_strings) {
932   DCHECK(localized_strings);
933   internet_options_strings::RegisterLocalizedStrings(localized_strings);
934 
935   std::string owner;
936   chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
937   localized_strings->SetString("ownerUserId", base::UTF8ToUTF16(owner));
938 
939   base::DictionaryValue* network_dictionary = new base::DictionaryValue;
940   FillNetworkInfo(network_dictionary);
941   localized_strings->Set("networkData", network_dictionary);
942 }
943 
InitializePage()944 void InternetOptionsHandler::InitializePage() {
945   base::DictionaryValue dictionary;
946   dictionary.SetString(kTagCellular,
947       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK));
948   dictionary.SetString(kTagWifi,
949       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK));
950   dictionary.SetString(kTagVpn,
951       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_VPN));
952   web_ui()->CallJavascriptFunction(kSetDefaultNetworkIconsFunction,
953                                    dictionary);
954   NetworkHandler::Get()->network_state_handler()->RequestScan();
955   RefreshNetworkData();
956   UpdateLoggedInUserType();
957 }
958 
RegisterMessages()959 void InternetOptionsHandler::RegisterMessages() {
960   // Setup handlers specific to this panel.
961   web_ui()->RegisterMessageCallback(kNetworkCommandMessage,
962       base::Bind(&InternetOptionsHandler::NetworkCommandCallback,
963                  base::Unretained(this)));
964   web_ui()->RegisterMessageCallback(kRefreshNetworksMessage,
965       base::Bind(&InternetOptionsHandler::RefreshNetworksCallback,
966                  base::Unretained(this)));
967   web_ui()->RegisterMessageCallback(kSetPreferNetworkMessage,
968       base::Bind(&InternetOptionsHandler::SetPreferNetworkCallback,
969                  base::Unretained(this)));
970   web_ui()->RegisterMessageCallback(kSetAutoConnectMessage,
971       base::Bind(&InternetOptionsHandler::SetAutoConnectCallback,
972                  base::Unretained(this)));
973   web_ui()->RegisterMessageCallback(kSetIPConfigMessage,
974       base::Bind(&InternetOptionsHandler::SetIPConfigCallback,
975                  base::Unretained(this)));
976   web_ui()->RegisterMessageCallback(kEnableWifiMessage,
977       base::Bind(&InternetOptionsHandler::EnableWifiCallback,
978                  base::Unretained(this)));
979   web_ui()->RegisterMessageCallback(kDisableWifiMessage,
980       base::Bind(&InternetOptionsHandler::DisableWifiCallback,
981                  base::Unretained(this)));
982   web_ui()->RegisterMessageCallback(kEnableCellularMessage,
983       base::Bind(&InternetOptionsHandler::EnableCellularCallback,
984                  base::Unretained(this)));
985   web_ui()->RegisterMessageCallback(kDisableCellularMessage,
986       base::Bind(&InternetOptionsHandler::DisableCellularCallback,
987                  base::Unretained(this)));
988   web_ui()->RegisterMessageCallback(kEnableWimaxMessage,
989       base::Bind(&InternetOptionsHandler::EnableWimaxCallback,
990                  base::Unretained(this)));
991   web_ui()->RegisterMessageCallback(kDisableWimaxMessage,
992       base::Bind(&InternetOptionsHandler::DisableWimaxCallback,
993                  base::Unretained(this)));
994   web_ui()->RegisterMessageCallback(kBuyDataPlanMessage,
995       base::Bind(&InternetOptionsHandler::BuyDataPlanCallback,
996                  base::Unretained(this)));
997   web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage,
998       base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback,
999                  base::Unretained(this)));
1000   web_ui()->RegisterMessageCallback(kSetApnMessage,
1001       base::Bind(&InternetOptionsHandler::SetApnCallback,
1002                  base::Unretained(this)));
1003   web_ui()->RegisterMessageCallback(kSetCarrierMessage,
1004       base::Bind(&InternetOptionsHandler::SetCarrierCallback,
1005                  base::Unretained(this)));
1006   web_ui()->RegisterMessageCallback(kSetSimCardLockMessage,
1007       base::Bind(&InternetOptionsHandler::SetSimCardLockCallback,
1008                  base::Unretained(this)));
1009   web_ui()->RegisterMessageCallback(kChangePinMessage,
1010       base::Bind(&InternetOptionsHandler::ChangePinCallback,
1011                  base::Unretained(this)));
1012   web_ui()->RegisterMessageCallback(kSetServerHostname,
1013       base::Bind(&InternetOptionsHandler::SetServerHostnameCallback,
1014                  base::Unretained(this)));
1015 }
1016 
EnableWifiCallback(const base::ListValue * args)1017 void InternetOptionsHandler::EnableWifiCallback(const base::ListValue* args) {
1018   content::RecordAction(base::UserMetricsAction("Options_NetworkWifiToggle"));
1019   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
1020       NetworkTypePattern::WiFi(), true,
1021       base::Bind(&ShillError, "EnableWifiCallback"));
1022 }
1023 
DisableWifiCallback(const base::ListValue * args)1024 void InternetOptionsHandler::DisableWifiCallback(const base::ListValue* args) {
1025   content::RecordAction(base::UserMetricsAction("Options_NetworkWifiToggle"));
1026   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
1027       NetworkTypePattern::WiFi(), false,
1028       base::Bind(&ShillError, "DisableWifiCallback"));
1029 }
1030 
EnableCellularCallback(const base::ListValue * args)1031 void InternetOptionsHandler::EnableCellularCallback(
1032     const base::ListValue* args) {
1033   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
1034   const DeviceState* device =
1035       handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
1036   if (!device) {
1037     LOG(ERROR) << "Mobile device not found.";
1038     return;
1039   }
1040   if (!device->sim_lock_type().empty()) {
1041     SimDialogDelegate::ShowDialog(GetNativeWindow(),
1042                                   SimDialogDelegate::SIM_DIALOG_UNLOCK);
1043     return;
1044   }
1045   if (!handler->IsTechnologyEnabled(NetworkTypePattern::Cellular())) {
1046     handler->SetTechnologyEnabled(
1047         NetworkTypePattern::Cellular(), true,
1048         base::Bind(&ShillError, "EnableCellularCallback"));
1049     return;
1050   }
1051   if (device->IsSimAbsent()) {
1052     mobile_config_ui::DisplayConfigDialog();
1053     return;
1054   }
1055   LOG(ERROR) << "EnableCellularCallback called for enabled mobile device";
1056 }
1057 
DisableCellularCallback(const base::ListValue * args)1058 void InternetOptionsHandler::DisableCellularCallback(
1059     const base::ListValue* args) {
1060   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
1061       NetworkTypePattern::Mobile(), false,
1062       base::Bind(&ShillError, "DisableCellularCallback"));
1063 }
1064 
EnableWimaxCallback(const base::ListValue * args)1065 void InternetOptionsHandler::EnableWimaxCallback(const base::ListValue* args) {
1066   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
1067       NetworkTypePattern::Wimax(), true,
1068       base::Bind(&ShillError, "EnableWimaxCallback"));
1069 }
1070 
DisableWimaxCallback(const base::ListValue * args)1071 void InternetOptionsHandler::DisableWimaxCallback(const base::ListValue* args) {
1072   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
1073       NetworkTypePattern::Wimax(), false,
1074       base::Bind(&ShillError, "DisableWimaxCallback"));
1075 }
1076 
ShowMorePlanInfoCallback(const base::ListValue * args)1077 void InternetOptionsHandler::ShowMorePlanInfoCallback(
1078     const base::ListValue* args) {
1079   if (!web_ui())
1080     return;
1081   std::string service_path;
1082   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
1083     NOTREACHED();
1084     return;
1085   }
1086   ash::network_connect::ShowMobileSetup(service_path);
1087 }
1088 
BuyDataPlanCallback(const base::ListValue * args)1089 void InternetOptionsHandler::BuyDataPlanCallback(const base::ListValue* args) {
1090   if (!web_ui())
1091     return;
1092   std::string service_path;
1093   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
1094     NOTREACHED();
1095     return;
1096   }
1097   ash::network_connect::ShowMobileSetup(service_path);
1098 }
1099 
SetApnCallback(const base::ListValue * args)1100 void InternetOptionsHandler::SetApnCallback(const base::ListValue* args) {
1101   std::string service_path;
1102   if (!args->GetString(0, &service_path)) {
1103     NOTREACHED();
1104     return;
1105   }
1106   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1107       service_path,
1108       base::Bind(&InternetOptionsHandler::SetApnProperties,
1109                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
1110       base::Bind(&ShillError, "SetApnCallback"));
1111 }
1112 
SetApnProperties(const base::ListValue * args,const std::string & service_path,const base::DictionaryValue & shill_properties)1113 void InternetOptionsHandler::SetApnProperties(
1114     const base::ListValue* args,
1115     const std::string& service_path,
1116     const base::DictionaryValue& shill_properties) {
1117   std::string apn, username, password;
1118   if (!args->GetString(1, &apn) ||
1119       !args->GetString(2, &username) ||
1120       !args->GetString(3, &password)) {
1121     NOTREACHED();
1122     return;
1123   }
1124   NET_LOG_EVENT("SetApnCallback", service_path);
1125 
1126   if (apn.empty()) {
1127     std::vector<std::string> properties_to_clear;
1128     properties_to_clear.push_back(shill::kCellularApnProperty);
1129     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
1130       service_path, properties_to_clear,
1131       base::Bind(&base::DoNothing),
1132       base::Bind(&ShillError, "ClearCellularApnProperties"));
1133     return;
1134   }
1135 
1136   const base::DictionaryValue* shill_apn_dict = NULL;
1137   std::string network_id;
1138   if (shill_properties.GetDictionaryWithoutPathExpansion(
1139           shill::kCellularApnProperty, &shill_apn_dict)) {
1140     shill_apn_dict->GetStringWithoutPathExpansion(
1141         shill::kApnNetworkIdProperty, &network_id);
1142   }
1143   base::DictionaryValue properties;
1144   base::DictionaryValue* apn_dict = new base::DictionaryValue;
1145   apn_dict->SetStringWithoutPathExpansion(shill::kApnProperty, apn);
1146   apn_dict->SetStringWithoutPathExpansion(shill::kApnNetworkIdProperty,
1147                                           network_id);
1148   apn_dict->SetStringWithoutPathExpansion(shill::kApnUsernameProperty,
1149                                           username);
1150   apn_dict->SetStringWithoutPathExpansion(shill::kApnPasswordProperty,
1151                                           password);
1152   properties.SetWithoutPathExpansion(shill::kCellularApnProperty, apn_dict);
1153   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
1154       service_path, properties,
1155       base::Bind(&base::DoNothing),
1156       base::Bind(&ShillError, "SetApnProperties"));
1157 }
1158 
CarrierStatusCallback()1159 void InternetOptionsHandler::CarrierStatusCallback() {
1160   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
1161   const DeviceState* device =
1162       handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
1163   if (device && (device->carrier() == shill::kCarrierSprint)) {
1164     const NetworkState* network =
1165         handler->FirstNetworkByType(NetworkTypePattern::Cellular());
1166     if (network) {
1167       ash::network_connect::ActivateCellular(network->path());
1168       UpdateConnectionData(network->path());
1169     }
1170   }
1171   UpdateCarrier();
1172 }
1173 
SetCarrierCallback(const base::ListValue * args)1174 void InternetOptionsHandler::SetCarrierCallback(const base::ListValue* args) {
1175   std::string service_path;
1176   std::string carrier;
1177   if (args->GetSize() != 2 ||
1178       !args->GetString(0, &service_path) ||
1179       !args->GetString(1, &carrier)) {
1180     NOTREACHED();
1181     return;
1182   }
1183   const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
1184       GetDeviceStateByType(NetworkTypePattern::Cellular());
1185   if (!device) {
1186     LOG(WARNING) << "SetCarrierCallback with no cellular device.";
1187     return;
1188   }
1189   NetworkHandler::Get()->network_device_handler()->SetCarrier(
1190       device->path(),
1191       carrier,
1192       base::Bind(&InternetOptionsHandler::CarrierStatusCallback,
1193                  weak_factory_.GetWeakPtr()),
1194       base::Bind(&ShillError, "SetCarrierCallback"));
1195 }
1196 
SetSimCardLockCallback(const base::ListValue * args)1197 void InternetOptionsHandler::SetSimCardLockCallback(
1198     const base::ListValue* args) {
1199   bool require_pin_new_value;
1200   if (!args->GetBoolean(0, &require_pin_new_value)) {
1201     NOTREACHED();
1202     return;
1203   }
1204   // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL.
1205   // 2. Dialog will ask for current PIN in any case.
1206   // 3. If card is locked it will first call PIN unlock operation
1207   // 4. Then it will call Set RequirePin, passing the same PIN.
1208   // 5. We'll get notified by REQUIRE_PIN_SETTING_CHANGE_ENDED notification.
1209   SimDialogDelegate::SimDialogMode mode;
1210   if (require_pin_new_value)
1211     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON;
1212   else
1213     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF;
1214   SimDialogDelegate::ShowDialog(GetNativeWindow(), mode);
1215 }
1216 
ChangePinCallback(const base::ListValue * args)1217 void InternetOptionsHandler::ChangePinCallback(const base::ListValue* args) {
1218   SimDialogDelegate::ShowDialog(GetNativeWindow(),
1219                                 SimDialogDelegate::SIM_DIALOG_CHANGE_PIN);
1220 }
1221 
RefreshNetworksCallback(const base::ListValue * args)1222 void InternetOptionsHandler::RefreshNetworksCallback(
1223     const base::ListValue* args) {
1224   NetworkHandler::Get()->network_state_handler()->RequestScan();
1225 }
1226 
GetIconDataUrl(int resource_id) const1227 std::string InternetOptionsHandler::GetIconDataUrl(int resource_id) const {
1228   gfx::ImageSkia* icon =
1229       ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
1230   gfx::ImageSkiaRep image_rep = icon->GetRepresentation(
1231       web_ui()->GetDeviceScaleFactor());
1232   return webui::GetBitmapDataUrl(image_rep.sk_bitmap());
1233 }
1234 
RefreshNetworkData()1235 void InternetOptionsHandler::RefreshNetworkData() {
1236   base::DictionaryValue dictionary;
1237   FillNetworkInfo(&dictionary);
1238   web_ui()->CallJavascriptFunction(
1239       kRefreshNetworkDataFunction, dictionary);
1240 }
1241 
UpdateConnectionData(const std::string & service_path)1242 void InternetOptionsHandler::UpdateConnectionData(
1243     const std::string& service_path) {
1244   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1245       service_path,
1246       base::Bind(&InternetOptionsHandler::UpdateConnectionDataCallback,
1247                  weak_factory_.GetWeakPtr()),
1248       base::Bind(&ShillError, "UpdateConnectionData"));
1249 }
1250 
UpdateConnectionDataCallback(const std::string & service_path,const base::DictionaryValue & shill_properties)1251 void InternetOptionsHandler::UpdateConnectionDataCallback(
1252     const std::string& service_path,
1253     const base::DictionaryValue& shill_properties) {
1254   const NetworkState* network = GetNetworkState(service_path);
1255   if (!network)
1256     return;
1257   base::DictionaryValue dictionary;
1258   PopulateConnectionDetails(network, shill_properties, &dictionary);
1259   web_ui()->CallJavascriptFunction(kUpdateConnectionDataFunction, dictionary);
1260 }
1261 
UpdateCarrier()1262 void InternetOptionsHandler::UpdateCarrier() {
1263   web_ui()->CallJavascriptFunction(kUpdateCarrierFunction);
1264 }
1265 
DeviceListChanged()1266 void InternetOptionsHandler::DeviceListChanged() {
1267   if (!web_ui())
1268     return;
1269   RefreshNetworkData();
1270 }
1271 
NetworkListChanged()1272 void InternetOptionsHandler::NetworkListChanged() {
1273   if (!web_ui())
1274     return;
1275   RefreshNetworkData();
1276 }
1277 
NetworkConnectionStateChanged(const NetworkState * network)1278 void InternetOptionsHandler::NetworkConnectionStateChanged(
1279     const NetworkState* network) {
1280   if (!web_ui())
1281     return;
1282   // Update the connection data for the detailed view when the connection state
1283   // of any network changes.
1284   if (!details_path_.empty())
1285     UpdateConnectionData(details_path_);
1286 }
1287 
NetworkPropertiesUpdated(const NetworkState * network)1288 void InternetOptionsHandler::NetworkPropertiesUpdated(
1289     const NetworkState* network) {
1290   if (!web_ui())
1291     return;
1292   RefreshNetworkData();
1293   UpdateConnectionData(network->path());
1294 }
1295 
LoggedInStateChanged()1296 void InternetOptionsHandler::LoggedInStateChanged() {
1297   UpdateLoggedInUserType();
1298 }
1299 
UpdateLoggedInUserType()1300 void InternetOptionsHandler::UpdateLoggedInUserType() {
1301   if (!web_ui())
1302     return;
1303   base::StringValue login_type(
1304       LoggedInUserTypeToJSString(LoginState::Get()->GetLoggedInUserType()));
1305   web_ui()->CallJavascriptFunction(kUpdateLoggedInUserTypeFunction, login_type);
1306 }
1307 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)1308 void InternetOptionsHandler::Observe(
1309     int type,
1310     const content::NotificationSource& source,
1311     const content::NotificationDetails& details) {
1312   if (type == chrome::NOTIFICATION_REQUIRE_PIN_SETTING_CHANGE_ENDED) {
1313     base::FundamentalValue require_pin(*content::Details<bool>(details).ptr());
1314     web_ui()->CallJavascriptFunction(
1315         kUpdateSecurityTabFunction, require_pin);
1316   } else if (type == chrome::NOTIFICATION_ENTER_PIN_ENDED) {
1317     // We make an assumption (which is valid for now) that the SIM
1318     // unlock dialog is put up only when the user is trying to enable
1319     // mobile data.
1320     bool cancelled = *content::Details<bool>(details).ptr();
1321     if (cancelled)
1322       RefreshNetworkData();
1323     // The case in which the correct PIN was entered and the SIM is
1324     // now unlocked is handled in NetworkMenuButton.
1325   }
1326 }
1327 
SetServerHostnameCallback(const base::ListValue * args)1328 void InternetOptionsHandler::SetServerHostnameCallback(
1329     const base::ListValue* args) {
1330   std::string service_path, server_hostname;
1331   if (args->GetSize() < 2 ||
1332       !args->GetString(0, &service_path) ||
1333       !args->GetString(1, &server_hostname)) {
1334     NOTREACHED();
1335     return;
1336   }
1337   SetNetworkProperty(service_path, shill::kProviderHostProperty,
1338                      base::Value::CreateStringValue(server_hostname));
1339 }
1340 
SetPreferNetworkCallback(const base::ListValue * args)1341 void InternetOptionsHandler::SetPreferNetworkCallback(
1342     const base::ListValue* args) {
1343   std::string service_path, prefer_network_str;
1344   if (args->GetSize() < 2 ||
1345       !args->GetString(0, &service_path) ||
1346       !args->GetString(1, &prefer_network_str)) {
1347     NOTREACHED();
1348     return;
1349   }
1350   content::RecordAction(base::UserMetricsAction("Options_NetworkSetPrefer"));
1351   int priority = (prefer_network_str == kTagTrue) ? kPreferredPriority : 0;
1352   SetNetworkProperty(service_path, shill::kPriorityProperty,
1353                      base::Value::CreateIntegerValue(priority));
1354 }
1355 
SetAutoConnectCallback(const base::ListValue * args)1356 void InternetOptionsHandler::SetAutoConnectCallback(
1357     const base::ListValue* args) {
1358   std::string service_path, auto_connect_str;
1359   if (args->GetSize() < 2 ||
1360       !args->GetString(0, &service_path) ||
1361       !args->GetString(1, &auto_connect_str)) {
1362     NOTREACHED();
1363     return;
1364   }
1365   content::RecordAction(base::UserMetricsAction("Options_NetworkAutoConnect"));
1366   bool auto_connect = auto_connect_str == kTagTrue;
1367   SetNetworkProperty(service_path, shill::kAutoConnectProperty,
1368                      base::Value::CreateBooleanValue(auto_connect));
1369 }
1370 
SetIPConfigCallback(const base::ListValue * args)1371 void InternetOptionsHandler::SetIPConfigCallback(const base::ListValue* args) {
1372   std::string service_path;
1373   if (!args->GetString(0, &service_path)) {
1374     NOTREACHED();
1375     return;
1376   }
1377   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1378       service_path,
1379       base::Bind(&InternetOptionsHandler::SetIPConfigProperties,
1380                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
1381       base::Bind(&ShillError, "SetIPConfigCallback"));
1382 }
1383 
SetIPConfigProperties(const base::ListValue * args,const std::string & service_path,const base::DictionaryValue & shill_properties)1384 void InternetOptionsHandler::SetIPConfigProperties(
1385     const base::ListValue* args,
1386     const std::string& service_path,
1387     const base::DictionaryValue& shill_properties) {
1388   std::string address, netmask, gateway, name_server_type, name_servers;
1389   bool dhcp_for_ip;
1390   if (!args->GetBoolean(1, &dhcp_for_ip) ||
1391       !args->GetString(2, &address) ||
1392       !args->GetString(3, &netmask) ||
1393       !args->GetString(4, &gateway) ||
1394       !args->GetString(5, &name_server_type) ||
1395       !args->GetString(6, &name_servers)) {
1396     NOTREACHED();
1397     return;
1398   }
1399   NET_LOG_USER("SetIPConfigProperties", service_path);
1400 
1401   bool request_reconnect = false;
1402   std::vector<std::string> properties_to_clear;
1403   base::DictionaryValue properties_to_set;
1404 
1405   if (dhcp_for_ip) {
1406     request_reconnect |= AppendPropertyKeyIfPresent(
1407         shill::kStaticIPAddressProperty,
1408         shill_properties, &properties_to_clear);
1409     request_reconnect |= AppendPropertyKeyIfPresent(
1410         shill::kStaticIPPrefixlenProperty,
1411         shill_properties, &properties_to_clear);
1412     request_reconnect |= AppendPropertyKeyIfPresent(
1413         shill::kStaticIPGatewayProperty,
1414         shill_properties, &properties_to_clear);
1415   } else {
1416     request_reconnect |= AddStringPropertyIfChanged(
1417         shill::kStaticIPAddressProperty,
1418         address, shill_properties, &properties_to_set);
1419     int prefixlen = network_util::NetmaskToPrefixLength(netmask);
1420     if (prefixlen < 0) {
1421       LOG(ERROR) << "Invalid prefix length for: " << service_path
1422                  << " with netmask " << netmask;
1423       prefixlen = 0;
1424     }
1425     request_reconnect |= AddIntegerPropertyIfChanged(
1426         shill::kStaticIPPrefixlenProperty,
1427         prefixlen, shill_properties, &properties_to_set);
1428     request_reconnect |= AddStringPropertyIfChanged(
1429         shill::kStaticIPGatewayProperty,
1430         gateway, shill_properties, &properties_to_set);
1431   }
1432 
1433   if (name_server_type == kNameServerTypeAutomatic) {
1434     AppendPropertyKeyIfPresent(shill::kStaticIPNameServersProperty,
1435                                shill_properties, &properties_to_clear);
1436   } else {
1437     if (name_server_type == kNameServerTypeGoogle)
1438       name_servers = kGoogleNameServers;
1439     AddStringPropertyIfChanged(
1440         shill::kStaticIPNameServersProperty,
1441         name_servers, shill_properties, &properties_to_set);
1442   }
1443 
1444   if (!properties_to_clear.empty()) {
1445     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
1446       service_path, properties_to_clear,
1447       base::Bind(&base::DoNothing),
1448       base::Bind(&ShillError, "ClearIPConfigProperties"));
1449   }
1450   if (!properties_to_set.empty()) {
1451     NetworkHandler::Get()->network_configuration_handler()->SetProperties(
1452         service_path, properties_to_set,
1453         base::Bind(&base::DoNothing),
1454         base::Bind(&ShillError, "SetIPConfigProperties"));
1455   }
1456   std::string device_path;
1457   shill_properties.GetStringWithoutPathExpansion(
1458       shill::kDeviceProperty, &device_path);
1459   if (!device_path.empty()) {
1460     base::Closure callback = base::Bind(&base::DoNothing);
1461     // If auto config or a static IP property changed, we need to reconnect
1462     // to the network.
1463     if (request_reconnect)
1464       callback = base::Bind(&RequestReconnect, service_path, GetNativeWindow());
1465     NetworkHandler::Get()->network_device_handler()->RequestRefreshIPConfigs(
1466         device_path,
1467         callback,
1468         base::Bind(&ShillError, "RequestRefreshIPConfigs"));
1469   }
1470 }
1471 
PopulateDictionaryDetailsCallback(const std::string & service_path,const base::DictionaryValue & shill_properties)1472 void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
1473     const std::string& service_path,
1474     const base::DictionaryValue& shill_properties) {
1475   const NetworkState* network = GetNetworkState(service_path);
1476   if (!network) {
1477     LOG(ERROR) << "Network properties not found: " << service_path;
1478     return;
1479   }
1480 
1481   details_path_ = service_path;
1482 
1483   ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
1484   const base::DictionaryValue* onc =
1485       onc::FindPolicyForActiveUser(network->guid(), &onc_source);
1486   const NetworkPropertyUIData property_ui_data(onc_source);
1487 
1488   base::DictionaryValue dictionary;
1489 
1490   // Device hardware address
1491   const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
1492       GetDeviceState(network->device_path());
1493   if (device) {
1494     dictionary.SetString(
1495         kTagHardwareAddress,
1496         network_util::FormattedMacAddress(device->mac_address()));
1497   }
1498 
1499   // IP config
1500   scoped_ptr<base::DictionaryValue> ipconfig_dhcp(new base::DictionaryValue);
1501   ipconfig_dhcp->SetString(kIpConfigAddress, network->ip_address());
1502   ipconfig_dhcp->SetString(kIpConfigNetmask, network->GetNetmask());
1503   ipconfig_dhcp->SetString(kIpConfigGateway, network->gateway());
1504   std::string ipconfig_name_servers = network->GetDnsServersAsString();
1505   ipconfig_dhcp->SetString(kIpConfigNameServers, ipconfig_name_servers);
1506   ipconfig_dhcp->SetString(kIpConfigWebProxyAutoDiscoveryUrl,
1507                            network->web_proxy_auto_discovery_url().spec());
1508   SetValueDictionary(&dictionary,
1509                      kDictionaryIpConfig,
1510                      ipconfig_dhcp.release(),
1511                      property_ui_data);
1512 
1513   std::string name_server_type = kNameServerTypeAutomatic;
1514   int automatic_ip_config = 0;
1515   scoped_ptr<base::DictionaryValue> static_ip_dict(
1516       BuildIPInfoDictionary(shill_properties, true, &automatic_ip_config));
1517   dictionary.SetBoolean(kIpConfigAutoConfig, automatic_ip_config == 0);
1518   DCHECK(automatic_ip_config == 3 || automatic_ip_config == 0)
1519       << "UI doesn't support automatic specification of individual "
1520       << "static IP parameters.";
1521   scoped_ptr<base::DictionaryValue> saved_ip_dict(
1522       BuildIPInfoDictionary(shill_properties, false, NULL));
1523   dictionary.Set(kDictionarySavedIp, saved_ip_dict.release());
1524 
1525   // Determine what kind of name server setting we have by comparing the
1526   // StaticIP and Google values with the ipconfig values.
1527   std::string static_ip_nameservers;
1528   static_ip_dict->GetString(kIpConfigNameServers, &static_ip_nameservers);
1529   if (!static_ip_nameservers.empty() &&
1530       static_ip_nameservers == ipconfig_name_servers) {
1531     name_server_type = kNameServerTypeUser;
1532   }
1533   if (ipconfig_name_servers == kGoogleNameServers) {
1534     name_server_type = kNameServerTypeGoogle;
1535   }
1536   SetValueDictionary(&dictionary,
1537                      kDictionaryStaticIp,
1538                      static_ip_dict.release(),
1539                      property_ui_data);
1540 
1541   std::string type = network->type();
1542   dictionary.SetString(kTagType, type);
1543   dictionary.SetString(kTagServicePath, network->path());
1544   dictionary.SetString(kTagNameServerType, name_server_type);
1545   dictionary.SetString(kTagNameServersGoogle, kGoogleNameServers);
1546 
1547   // Only show proxy for remembered networks.
1548   dictionary.SetBoolean(kTagShowProxy, !network->profile_path().empty());
1549 
1550   // Enable static ip config for Ethernet or WiFi.
1551   bool staticIPConfig = network->Matches(NetworkTypePattern::Ethernet()) ||
1552                         type == shill::kTypeWifi;
1553   dictionary.SetBoolean(kTagShowStaticIPConfig, staticIPConfig);
1554 
1555   dictionary.SetBoolean(kTagShowPreferred, !network->profile_path().empty());
1556   int priority = 0;
1557   shill_properties.GetIntegerWithoutPathExpansion(
1558       shill::kPriorityProperty, &priority);
1559   bool preferred = priority > 0;
1560   SetValueDictionary(&dictionary, kTagPreferred,
1561                      new base::FundamentalValue(preferred),
1562                      property_ui_data);
1563 
1564   NetworkPropertyUIData auto_connect_ui_data(onc_source);
1565   std::string onc_path_to_auto_connect;
1566   if (type == shill::kTypeWifi) {
1567     content::RecordAction(
1568         base::UserMetricsAction("Options_NetworkShowDetailsWifi"));
1569     if (network->IsConnectedState()) {
1570       content::RecordAction(
1571           base::UserMetricsAction("Options_NetworkShowDetailsWifiConnected"));
1572     }
1573     onc_path_to_auto_connect =
1574         ::onc::network_config::WifiProperty(::onc::wifi::kAutoConnect);
1575   } else if (type == shill::kTypeVPN) {
1576     content::RecordAction(
1577         base::UserMetricsAction("Options_NetworkShowDetailsVPN"));
1578     if (network->IsConnectedState()) {
1579       content::RecordAction(
1580           base::UserMetricsAction("Options_NetworkShowDetailsVPNConnected"));
1581     }
1582     onc_path_to_auto_connect = ::onc::network_config::VpnProperty(
1583         ::onc::vpn::kAutoConnect);
1584   } else if (type == shill::kTypeCellular) {
1585     content::RecordAction(
1586         base::UserMetricsAction("Options_NetworkShowDetailsCellular"));
1587     if (network->IsConnectedState()) {
1588       content::RecordAction(base::UserMetricsAction(
1589           "Options_NetworkShowDetailsCellularConnected"));
1590     }
1591   }
1592   if (!onc_path_to_auto_connect.empty()) {
1593     auto_connect_ui_data.ParseOncProperty(
1594         onc_source, onc, onc_path_to_auto_connect);
1595   }
1596   bool auto_connect = false;
1597   shill_properties.GetBooleanWithoutPathExpansion(
1598       shill::kAutoConnectProperty, &auto_connect);
1599   SetAutoconnectValueDictionary(network->IsPrivate(),
1600                                 onc_source,
1601                                 auto_connect,
1602                                 auto_connect_ui_data,
1603                                 &dictionary);
1604 
1605   PopulateConnectionDetails(network, shill_properties, &dictionary);
1606 
1607   // Show details dialog
1608   web_ui()->CallJavascriptFunction(kShowDetailedInfoFunction, dictionary);
1609 }
1610 
GetNativeWindow() const1611 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
1612   return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
1613 }
1614 
NetworkCommandCallback(const base::ListValue * args)1615 void InternetOptionsHandler::NetworkCommandCallback(
1616     const base::ListValue* args) {
1617   std::string type;
1618   std::string service_path;
1619   std::string command;
1620   if (args->GetSize() != 3 ||
1621       !args->GetString(0, &type) ||
1622       !args->GetString(1, &service_path) ||
1623       !args->GetString(2, &command)) {
1624     NOTREACHED();
1625     return;
1626   }
1627 
1628   // Process commands that do not require an existing network.
1629   if (command == kTagAddConnection) {
1630     if (CanAddNetworkType(type))
1631       AddConnection(type);
1632   } else if (command == kTagForget) {
1633     if (CanForgetNetworkType(type)) {
1634       NetworkHandler::Get()->network_configuration_handler()->
1635           RemoveConfiguration(
1636               service_path,
1637               base::Bind(&base::DoNothing),
1638               base::Bind(&ShillError, "NetworkCommand: " + command));
1639     }
1640   } else if (command == kTagOptions) {
1641     NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1642         service_path,
1643         base::Bind(&InternetOptionsHandler::PopulateDictionaryDetailsCallback,
1644                    weak_factory_.GetWeakPtr()),
1645         base::Bind(&ShillError, "NetworkCommand: " + command));
1646   } else if (command == kTagConnect) {
1647     const NetworkState* network = GetNetworkState(service_path);
1648     if (network && network->type() == shill::kTypeWifi)
1649       content::RecordAction(
1650           base::UserMetricsAction("Options_NetworkConnectToWifi"));
1651     else if (network && network->type() == shill::kTypeVPN)
1652       content::RecordAction(
1653           base::UserMetricsAction("Options_NetworkConnectToVPN"));
1654     ash::network_connect::ConnectToNetwork(service_path, GetNativeWindow());
1655   } else if (command == kTagDisconnect) {
1656     const NetworkState* network = GetNetworkState(service_path);
1657     if (network && network->type() == shill::kTypeWifi)
1658       content::RecordAction(
1659           base::UserMetricsAction("Options_NetworkDisconnectWifi"));
1660     else if (network && network->type() == shill::kTypeVPN)
1661       content::RecordAction(
1662           base::UserMetricsAction("Options_NetworkDisconnectVPN"));
1663     NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
1664         service_path,
1665         base::Bind(&base::DoNothing),
1666         base::Bind(&ShillError, "NetworkCommand: " + command));
1667   } else if (command == kTagConfigure) {
1668     NetworkConfigView::Show(service_path, GetNativeWindow());
1669   } else if (command == kTagActivate && type == shill::kTypeCellular) {
1670     ash::network_connect::ActivateCellular(service_path);
1671     // Activation may update network properties (e.g. ActivationState), so
1672     // request them here in case they change.
1673     UpdateConnectionData(service_path);
1674   } else {
1675     VLOG(1) << "Unknown command: " << command;
1676     NOTREACHED();
1677   }
1678 }
1679 
AddConnection(const std::string & type)1680 void InternetOptionsHandler::AddConnection(const std::string& type) {
1681   if (type == shill::kTypeWifi) {
1682     content::RecordAction(
1683         base::UserMetricsAction("Options_NetworkJoinOtherWifi"));
1684     NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow());
1685   } else if (type == shill::kTypeVPN) {
1686     content::RecordAction(
1687         base::UserMetricsAction("Options_NetworkJoinOtherVPN"));
1688     NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow());
1689   } else if (type == shill::kTypeCellular) {
1690     ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
1691   } else {
1692     NOTREACHED();
1693   }
1694 }
1695 
GetWiredList()1696 base::ListValue* InternetOptionsHandler::GetWiredList() {
1697   base::ListValue* list = new base::ListValue();
1698   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
1699       FirstNetworkByType(NetworkTypePattern::Ethernet());
1700   if (!network)
1701     return list;
1702   list->Append(
1703       BuildNetworkDictionary(network,
1704                              web_ui()->GetDeviceScaleFactor(),
1705                              Profile::FromWebUI(web_ui())->GetPrefs()));
1706   return list;
1707 }
1708 
GetWirelessList()1709 base::ListValue* InternetOptionsHandler::GetWirelessList() {
1710   base::ListValue* list = new base::ListValue();
1711 
1712   NetworkStateHandler::NetworkStateList networks;
1713   NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
1714       NetworkTypePattern::Wireless(), &networks);
1715   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
1716            networks.begin(); iter != networks.end(); ++iter) {
1717     list->Append(
1718         BuildNetworkDictionary(*iter,
1719                                web_ui()->GetDeviceScaleFactor(),
1720                                Profile::FromWebUI(web_ui())->GetPrefs()));
1721   }
1722 
1723   return list;
1724 }
1725 
GetVPNList()1726 base::ListValue* InternetOptionsHandler::GetVPNList() {
1727   base::ListValue* list = new base::ListValue();
1728 
1729   NetworkStateHandler::NetworkStateList networks;
1730   NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
1731       NetworkTypePattern::VPN(), &networks);
1732   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
1733            networks.begin(); iter != networks.end(); ++iter) {
1734     list->Append(
1735         BuildNetworkDictionary(*iter,
1736                                web_ui()->GetDeviceScaleFactor(),
1737                                Profile::FromWebUI(web_ui())->GetPrefs()));
1738   }
1739 
1740   return list;
1741 }
1742 
GetRememberedList()1743 base::ListValue* InternetOptionsHandler::GetRememberedList() {
1744   base::ListValue* list = new base::ListValue();
1745 
1746   NetworkStateHandler::NetworkStateList networks;
1747   NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
1748       NetworkTypePattern::Default(),
1749       true /* configured_only */,
1750       false /* visible_only */,
1751       0 /* no limit */,
1752       &networks);
1753   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
1754            networks.begin(); iter != networks.end(); ++iter) {
1755     const NetworkState* network = *iter;
1756     if (network->type() != shill::kTypeWifi &&
1757         network->type() != shill::kTypeVPN)
1758       continue;
1759     list->Append(
1760         BuildNetworkDictionary(network,
1761                                web_ui()->GetDeviceScaleFactor(),
1762                                Profile::FromWebUI(web_ui())->GetPrefs()));
1763   }
1764 
1765   return list;
1766 }
1767 
FillNetworkInfo(base::DictionaryValue * dictionary)1768 void InternetOptionsHandler::FillNetworkInfo(
1769     base::DictionaryValue* dictionary) {
1770   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
1771   dictionary->Set(kTagWiredList, GetWiredList());
1772   dictionary->Set(kTagWirelessList, GetWirelessList());
1773   dictionary->Set(kTagVpnList, GetVPNList());
1774   dictionary->Set(kTagRememberedList, GetRememberedList());
1775 
1776   dictionary->SetBoolean(
1777       kTagWifiAvailable,
1778       handler->IsTechnologyAvailable(NetworkTypePattern::WiFi()));
1779   dictionary->SetBoolean(
1780       kTagWifiEnabled,
1781       handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()));
1782 
1783   dictionary->SetBoolean(
1784       kTagCellularAvailable,
1785       handler->IsTechnologyAvailable(NetworkTypePattern::Mobile()));
1786   dictionary->SetBoolean(
1787       kTagCellularEnabled,
1788       handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()));
1789   const DeviceState* cellular =
1790       handler->GetDeviceStateByType(NetworkTypePattern::Mobile());
1791   dictionary->SetBoolean(
1792       kTagCellularSupportsScan,
1793       cellular && cellular->support_network_scan());
1794 
1795   dictionary->SetBoolean(
1796       kTagWimaxAvailable,
1797       handler->IsTechnologyAvailable(NetworkTypePattern::Wimax()));
1798   dictionary->SetBoolean(
1799       kTagWimaxEnabled,
1800       handler->IsTechnologyEnabled(NetworkTypePattern::Wimax()));
1801 }
1802 
1803 }  // namespace options
1804 }  // namespace chromeos
1805