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.
5 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
13 #include "ash/system/chromeos/network/network_connect.h"
14 #include "base/basictypes.h"
15 #include "base/bind.h"
16 #include "base/bind_helpers.h"
17 #include "base/command_line.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chromeos/mobile_config.h"
22 #include "chrome/browser/chromeos/net/onc_utils.h"
23 #include "chrome/browser/chromeos/options/network_config_view.h"
24 #include "chrome/browser/chromeos/options/network_property_ui_data.h"
25 #include "chrome/browser/chromeos/settings/cros_settings.h"
26 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
27 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
28 #include "chrome/browser/chromeos/ui/mobile_config_ui.h"
29 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h"
32 #include "chromeos/chromeos_switches.h"
33 #include "chromeos/network/device_state.h"
34 #include "chromeos/network/managed_network_configuration_handler.h"
35 #include "chromeos/network/network_configuration_handler.h"
36 #include "chromeos/network/network_connection_handler.h"
37 #include "chromeos/network/network_device_handler.h"
38 #include "chromeos/network/network_event_log.h"
39 #include "chromeos/network/network_ip_config.h"
40 #include "chromeos/network/network_profile.h"
41 #include "chromeos/network/network_profile_handler.h"
42 #include "chromeos/network/network_state.h"
43 #include "chromeos/network/network_state_handler.h"
44 #include "chromeos/network/network_util.h"
45 #include "chromeos/network/onc/onc_signature.h"
46 #include "chromeos/network/onc/onc_translator.h"
47 #include "chromeos/network/onc/onc_utils.h"
48 #include "components/onc/onc_constants.h"
49 #include "content/public/browser/user_metrics.h"
50 #include "content/public/browser/web_contents.h"
51 #include "content/public/browser/web_ui.h"
52 #include "grit/ash_resources.h"
53 #include "grit/ui_chromeos_resources.h"
54 #include "third_party/cros_system_api/dbus/service_constants.h"
55 #include "ui/base/resource/resource_bundle.h"
56 #include "ui/base/webui/web_ui_util.h"
57 #include "ui/chromeos/network/network_icon.h"
58 #include "ui/gfx/image/image_skia.h"
65 // Keys for the network description dictionary passed to the web ui. Make sure
66 // to keep the strings in sync with what the JavaScript side uses.
67 const char kNetworkInfoKeyIconURL[] = "iconURL";
68 const char kNetworkInfoKeyServicePath[] = "servicePath";
69 const char kNetworkInfoKeyPolicyManaged[] = "policyManaged";
71 // These are keys for getting IP information from the web ui.
72 const char kIpConfigAddress[] = "address";
73 const char kIpConfigPrefixLength[] = "prefixLength";
74 const char kIpConfigNetmask[] = "netmask";
75 const char kIpConfigGateway[] = "gateway";
76 const char kIpConfigNameServers[] = "nameServers";
77 const char kIpConfigAutoConfig[] = "ipAutoConfig";
78 const char kIpConfigWebProxyAutoDiscoveryUrl[] = "webProxyAutoDiscoveryUrl";
80 // These are types of name server selections from the web ui.
81 const char kNameServerTypeAutomatic[] = "automatic";
82 const char kNameServerTypeGoogle[] = "google";
83 const char kNameServerTypeUser[] = "user";
85 // These are dictionary names used to send data to the web ui.
86 const char kDictionaryIpConfig[] = "ipconfig";
87 const char kDictionaryStaticIp[] = "staticIP";
88 const char kDictionarySavedIp[] = "savedIP";
90 // Google public name servers (DNS).
91 const char kGoogleNameServers[] = "8.8.4.4,8.8.8.8";
93 // Functions we call in JavaScript.
94 const char kRefreshNetworkDataFunction[] =
95 "options.network.NetworkList.refreshNetworkData";
96 const char kSetDefaultNetworkIconsFunction[] =
97 "options.network.NetworkList.setDefaultNetworkIcons";
98 const char kShowDetailedInfoFunction[] =
99 "options.internet.DetailsInternetPage.showDetailedInfo";
100 const char kUpdateConnectionDataFunction[] =
101 "options.internet.DetailsInternetPage.updateConnectionData";
102 const char kUpdateCarrierFunction[] =
103 "options.internet.DetailsInternetPage.updateCarrier";
105 // These are used to register message handlers with JavaScript.
106 const char kBuyDataPlanMessage[] = "buyDataPlan";
107 const char kChangePinMessage[] = "changePin";
108 const char kDisableCellularMessage[] = "disableCellular";
109 const char kDisableWifiMessage[] = "disableWifi";
110 const char kDisableWimaxMessage[] = "disableWimax";
111 const char kEnableCellularMessage[] = "enableCellular";
112 const char kEnableWifiMessage[] = "enableWifi";
113 const char kEnableWimaxMessage[] = "enableWimax";
114 const char kNetworkCommandMessage[] = "networkCommand";
115 const char kRefreshNetworksMessage[] = "refreshNetworks";
116 const char kSetApnMessage[] = "setApn";
117 const char kSetAutoConnectMessage[] = "setAutoConnect";
118 const char kSetCarrierMessage[] = "setCarrier";
119 const char kSetIPConfigMessage[] = "setIPConfig";
120 const char kSetPreferNetworkMessage[] = "setPreferNetwork";
121 const char kSetServerHostname[] = "setServerHostname";
122 const char kSetSimCardLockMessage[] = "setSimCardLock";
123 const char kShowMorePlanInfoMessage[] = "showMorePlanInfo";
125 // These are strings used to communicate with JavaScript.
126 const char kTagActivate[] = "activate";
127 const char kTagActivationState[] = "activationState";
128 const char kTagAddConnection[] = "add";
129 const char kTagApn[] = "apn";
130 const char kTagCarrierSelectFlag[] = "showCarrierSelect";
131 const char kTagCarrierUrl[] = "carrierUrl";
132 const char kTagCellularAvailable[] = "cellularAvailable";
133 const char kTagCellularEnabled[] = "cellularEnabled";
134 const char kTagCellularSupportsScan[] = "cellularSupportsScan";
135 const char kTagConfigure[] = "configure";
136 const char kTagConnect[] = "connect";
137 const char kTagControlledBy[] = "controlledBy";
138 const char kTagDeviceConnected[] = "deviceConnected";
139 const char kTagDisconnect[] = "disconnect";
140 const char kTagErrorMessage[] = "errorMessage";
141 const char kTagForget[] = "forget";
142 const char kTagLanguage[] = "language";
143 const char kTagLastGoodApn[] = "lastGoodApn";
144 const char kTagLocalizedName[] = "localizedName";
145 const char kTagName[] = "name";
146 const char kTagNameServersGoogle[] = "nameServersGoogle";
147 const char kTagNameServerType[] = "nameServerType";
148 const char kTagNetworkId[] = "networkId";
149 const char kTagOptions[] = "options";
150 const char kTagPassword[] = "password";
151 const char kTagPolicy[] = "policy";
152 const char kTagPreferred[] = "preferred";
153 const char kTagProviderType[] = "providerType";
154 const char kTagProviderApnList[] = "providerApnList";
155 const char kTagRecommended[] = "recommended";
156 const char kTagRecommendedValue[] = "recommendedValue";
157 const char kTagRemembered[] = "remembered";
158 const char kTagRememberedList[] = "rememberedList";
159 const char kTagRestrictedPool[] = "restrictedPool";
160 const char kTagRoamingState[] = "roamingState";
161 const char kTagServerHostname[] = "serverHostname";
162 const char kTagCarriers[] = "carriers";
163 const char kTagCurrentCarrierIndex[] = "currentCarrierIndex";
164 const char kTagShared[] = "shared";
165 const char kTagShowActivateButton[] = "showActivateButton";
166 const char kTagShowViewAccountButton[] = "showViewAccountButton";
167 const char kTagSimCardLockEnabled[] = "simCardLockEnabled";
168 const char kTagSupportUrl[] = "supportUrl";
169 const char kTagTrue[] = "true";
170 const char kTagUsername[] = "username";
171 const char kTagValue[] = "value";
172 const char kTagVpnList[] = "vpnList";
173 const char kTagWifiAvailable[] = "wifiAvailable";
174 const char kTagWifiEnabled[] = "wifiEnabled";
175 const char kTagWimaxAvailable[] = "wimaxAvailable";
176 const char kTagWimaxEnabled[] = "wimaxEnabled";
177 const char kTagWiredList[] = "wiredList";
178 const char kTagWirelessList[] = "wirelessList";
180 const int kPreferredPriority = 1;
182 void ShillError(const std::string& function,
183 const std::string& error_name,
184 scoped_ptr<base::DictionaryValue> error_data) {
185 // UpdateConnectionData may send requests for stale services; ignore
187 if (function == "UpdateConnectionData" &&
188 error_name == network_handler::kDBusFailedError)
190 NET_LOG_ERROR("Shill Error from InternetOptionsHandler: " + error_name,
194 const NetworkState* GetNetworkState(const std::string& service_path) {
195 return NetworkHandler::Get()->network_state_handler()->
196 GetNetworkState(service_path);
199 void SetNetworkProperty(const std::string& service_path,
200 const std::string& property,
201 base::Value* value) {
202 NET_LOG_EVENT("SetNetworkProperty: " + property, service_path);
203 base::DictionaryValue properties;
204 properties.SetWithoutPathExpansion(property, value);
205 NetworkHandler::Get()->network_configuration_handler()->SetProperties(
206 service_path, properties,
207 base::Bind(&base::DoNothing),
208 base::Bind(&ShillError, "SetNetworkProperty"));
211 // Builds a dictionary with network information and an icon used for the
212 // NetworkList on the settings page. Ownership of the returned pointer is
213 // transferred to the caller.
214 base::DictionaryValue* BuildNetworkDictionary(
215 const NetworkState* network,
216 float icon_scale_factor,
217 const PrefService* profile_prefs) {
218 scoped_ptr<base::DictionaryValue> network_info =
219 network_util::TranslateNetworkStateToONC(network);
221 bool has_policy = onc::HasPolicyForNetwork(
222 profile_prefs, g_browser_process->local_state(), *network);
223 network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, has_policy);
225 std::string icon_url = ui::network_icon::GetImageUrlForNetwork(
226 network, ui::network_icon::ICON_TYPE_LIST, icon_scale_factor);
228 network_info->SetString(kNetworkInfoKeyIconURL, icon_url);
229 network_info->SetString(kNetworkInfoKeyServicePath, network->path());
231 return network_info.release();
234 // Pulls IP information out of a shill service properties dictionary. If
235 // |static_ip| is true, then it fetches "StaticIP.*" properties. If not, then it
236 // fetches "SavedIP.*" properties. Caller must take ownership of returned
237 // dictionary. If non-NULL, |ip_parameters_set| returns a count of the number
238 // of IP routing parameters that get set.
239 base::DictionaryValue* BuildIPInfoDictionary(
240 const base::DictionaryValue& shill_properties,
242 int* routing_parameters_set) {
243 std::string address_key;
244 std::string prefix_len_key;
245 std::string gateway_key;
246 std::string name_servers_key;
248 address_key = shill::kStaticIPAddressProperty;
249 prefix_len_key = shill::kStaticIPPrefixlenProperty;
250 gateway_key = shill::kStaticIPGatewayProperty;
251 name_servers_key = shill::kStaticIPNameServersProperty;
253 address_key = shill::kSavedIPAddressProperty;
254 prefix_len_key = shill::kSavedIPPrefixlenProperty;
255 gateway_key = shill::kSavedIPGatewayProperty;
256 name_servers_key = shill::kSavedIPNameServersProperty;
259 scoped_ptr<base::DictionaryValue> ip_info_dict(new base::DictionaryValue);
261 int routing_parameters = 0;
262 if (shill_properties.GetStringWithoutPathExpansion(address_key, &address)) {
263 ip_info_dict->SetString(kIpConfigAddress, address);
264 VLOG(2) << "Found " << address_key << ": " << address;
265 routing_parameters++;
268 if (shill_properties.GetIntegerWithoutPathExpansion(
269 prefix_len_key, &prefix_len)) {
270 ip_info_dict->SetInteger(kIpConfigPrefixLength, prefix_len);
271 std::string netmask = network_util::PrefixLengthToNetmask(prefix_len);
272 ip_info_dict->SetString(kIpConfigNetmask, netmask);
273 VLOG(2) << "Found " << prefix_len_key << ": "
274 << prefix_len << " (" << netmask << ")";
275 routing_parameters++;
278 if (shill_properties.GetStringWithoutPathExpansion(gateway_key, &gateway)) {
279 ip_info_dict->SetString(kIpConfigGateway, gateway);
280 VLOG(2) << "Found " << gateway_key << ": " << gateway;
281 routing_parameters++;
283 if (routing_parameters_set)
284 *routing_parameters_set = routing_parameters;
286 std::string name_servers;
287 if (shill_properties.GetStringWithoutPathExpansion(
288 name_servers_key, &name_servers)) {
289 ip_info_dict->SetString(kIpConfigNameServers, name_servers);
290 VLOG(2) << "Found " << name_servers_key << ": " << name_servers;
293 return ip_info_dict.release();
296 // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does and
297 // store it under |key| in |settings|. Takes ownership of |value|.
298 void SetValueDictionary(const char* key,
300 const NetworkPropertyUIData& ui_data,
301 base::DictionaryValue* settings) {
302 base::DictionaryValue* dict = new base::DictionaryValue();
303 // DictionaryValue::Set() takes ownership of |value|.
304 dict->Set(kTagValue, value);
305 settings->Set(key, dict);
307 const base::Value* recommended_value = ui_data.default_value();
308 if (ui_data.IsManaged())
309 dict->SetString(kTagControlledBy, kTagPolicy);
310 else if (recommended_value && recommended_value->Equals(value))
311 dict->SetString(kTagControlledBy, kTagRecommended);
313 if (recommended_value)
314 dict->Set(kTagRecommendedValue, recommended_value->DeepCopy());
317 const char* GetOncPolicyString(::onc::ONCSource onc_source) {
318 if (onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY)
319 return ::onc::kAugmentationDevicePolicy;
320 return ::onc::kAugmentationUserPolicy;
323 const char* GetOncEditableString(::onc::ONCSource onc_source) {
324 if (onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY)
325 return ::onc::kAugmentationDeviceEditable;
326 return ::onc::kAugmentationUserEditable;
329 const char* GetOncSettingString(::onc::ONCSource onc_source) {
330 if (onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY)
331 return ::onc::kAugmentationSharedSetting;
332 return ::onc::kAugmentationUserSetting;
335 // Creates a GetManagedProperties style dictionary and adds it to |settings|.
336 // |default_value| represents either the recommended value if |recommended|
337 // is true, or the enforced value if |recommended| is false.
338 // Note(stevenjb): This is bridge code until we use GetManagedProperties to
339 // retrieve Shill properties.
340 void SetManagedValueDictionary(const char* key,
341 const base::Value* value,
342 ::onc::ONCSource onc_source,
344 const base::Value* default_value,
345 base::DictionaryValue* settings) {
346 base::DictionaryValue* dict = new base::DictionaryValue();
347 settings->Set(key, dict);
350 dict->Set(::onc::kAugmentationActiveSetting, value->DeepCopy());
352 if (onc_source == ::onc::ONC_SOURCE_NONE)
356 // If an ONC property is 'Recommended' it can be edited by the user.
357 std::string editable = GetOncEditableString(onc_source);
358 dict->Set(editable, new base::FundamentalValue(true));
361 std::string policy_source = GetOncPolicyString(onc_source);
362 dict->Set(policy_source, default_value->DeepCopy());
363 if (recommended && !value->Equals(default_value)) {
364 std::string setting_source = GetOncSettingString(onc_source);
365 dict->Set(setting_source, value->DeepCopy());
366 dict->SetString(::onc::kAugmentationEffectiveSetting, setting_source);
368 dict->SetString(::onc::kAugmentationEffectiveSetting, policy_source);
373 std::string CopyStringFromDictionary(const base::DictionaryValue& source,
374 const std::string& src_key,
375 const std::string& dest_key,
376 base::DictionaryValue* dest) {
377 std::string string_value;
378 if (source.GetStringWithoutPathExpansion(src_key, &string_value))
379 dest->SetStringWithoutPathExpansion(dest_key, string_value);
383 // Fills |dictionary| with the configuration details of |vpn|. |onc| is required
384 // for augmenting the policy-managed information.
385 void PopulateVPNDetails(const NetworkState* vpn,
386 const base::DictionaryValue& shill_properties,
387 base::DictionaryValue* dictionary) {
388 // Name and Remembered are set in PopulateConnectionDetails().
389 // Provider properties are stored in the "Provider" dictionary.
390 const base::DictionaryValue* provider_properties = NULL;
391 if (!shill_properties.GetDictionaryWithoutPathExpansion(
392 shill::kProviderProperty, &provider_properties)) {
393 LOG(ERROR) << "No provider properties for VPN: " << vpn->path();
396 std::string provider_type;
397 provider_properties->GetStringWithoutPathExpansion(
398 shill::kTypeProperty, &provider_type);
399 dictionary->SetString(kTagProviderType,
400 internet_options_strings::ProviderTypeString(
402 *provider_properties));
404 std::string username;
405 if (provider_type == shill::kProviderOpenVpn) {
406 provider_properties->GetStringWithoutPathExpansion(
407 shill::kOpenVPNUserProperty, &username);
409 provider_properties->GetStringWithoutPathExpansion(
410 shill::kL2tpIpsecUserProperty, &username);
412 dictionary->SetString(kTagUsername, username);
414 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
415 const base::DictionaryValue* onc =
416 onc::FindPolicyForActiveUser(vpn->guid(), &onc_source);
418 NetworkPropertyUIData hostname_ui_data;
419 hostname_ui_data.ParseOncProperty(
422 ::onc::network_config::VpnProperty(::onc::vpn::kHost));
423 std::string provider_host;
424 provider_properties->GetStringWithoutPathExpansion(
425 shill::kHostProperty, &provider_host);
426 SetValueDictionary(kTagServerHostname,
427 new base::StringValue(provider_host),
432 // Given a list of supported carrier's by the device, return the index of
433 // the carrier the device is currently using.
434 int FindCurrentCarrierIndex(const base::ListValue* carriers,
435 const DeviceState* device) {
438 bool gsm = (device->technology_family() == shill::kTechnologyFamilyGsm);
440 for (base::ListValue::const_iterator it = carriers->begin();
441 it != carriers->end(); ++it, ++index) {
443 if (!(*it)->GetAsString(&value))
445 // For GSM devices the device name will be empty, so simply select
446 // the Generic UMTS carrier option if present.
447 if (gsm && (value == shill::kCarrierGenericUMTS))
449 // For other carriers, the service name will match the carrier name.
450 if (value == device->carrier())
456 void CreateDictionaryFromCellularApn(const base::DictionaryValue* apn,
457 base::DictionaryValue* dictionary) {
458 CopyStringFromDictionary(*apn, shill::kApnProperty, kTagApn, dictionary);
459 CopyStringFromDictionary(
460 *apn, shill::kApnNetworkIdProperty, kTagNetworkId, dictionary);
461 CopyStringFromDictionary(
462 *apn, shill::kApnUsernameProperty, kTagUsername, dictionary);
463 CopyStringFromDictionary(
464 *apn, shill::kApnPasswordProperty, kTagPassword, dictionary);
465 CopyStringFromDictionary(*apn, shill::kApnNameProperty, kTagName, dictionary);
466 CopyStringFromDictionary(
467 *apn, shill::kApnLocalizedNameProperty, kTagLocalizedName, dictionary);
468 CopyStringFromDictionary(
469 *apn, shill::kApnLanguageProperty, kTagLanguage, dictionary);
472 void PopulateCellularDetails(const NetworkState* cellular,
473 const base::DictionaryValue& shill_properties,
474 base::DictionaryValue* dictionary) {
475 dictionary->SetBoolean(kTagCarrierSelectFlag,
476 CommandLine::ForCurrentProcess()->HasSwitch(
477 chromeos::switches::kEnableCarrierSwitching));
478 // Cellular network / connection settings.
479 dictionary->SetString(kTagActivationState,
480 internet_options_strings::ActivationStateString(
481 cellular->activation_state()));
482 dictionary->SetString(kTagRoamingState,
483 internet_options_strings::RoamingStateString(
484 cellular->roaming()));
485 dictionary->SetString(kTagRestrictedPool,
486 internet_options_strings::RestrictedStateString(
487 cellular->connection_state()));
489 const base::DictionaryValue* olp = NULL;
490 if (shill_properties.GetDictionaryWithoutPathExpansion(
491 shill::kPaymentPortalProperty, &olp)) {
493 olp->GetStringWithoutPathExpansion(shill::kPaymentPortalURL, &url);
494 dictionary->SetString(kTagSupportUrl, url);
497 base::DictionaryValue* apn = new base::DictionaryValue;
498 const base::DictionaryValue* source_apn = NULL;
499 if (shill_properties.GetDictionaryWithoutPathExpansion(
500 shill::kCellularApnProperty, &source_apn)) {
501 CreateDictionaryFromCellularApn(source_apn, apn);
503 dictionary->Set(kTagApn, apn);
505 base::DictionaryValue* last_good_apn = new base::DictionaryValue;
506 if (shill_properties.GetDictionaryWithoutPathExpansion(
507 shill::kCellularLastGoodApnProperty, &source_apn)) {
508 CreateDictionaryFromCellularApn(source_apn, last_good_apn);
510 dictionary->Set(kTagLastGoodApn, last_good_apn);
512 // These default to empty and are only set if device != NULL.
513 std::string carrier_id;
517 const DeviceState* device =
518 NetworkHandler::Get()->network_state_handler()->GetDeviceState(
519 cellular->device_path());
521 const base::DictionaryValue& device_properties = device->properties();
522 ::onc::ONCSource onc_source;
523 NetworkHandler::Get()->managed_network_configuration_handler()->
524 FindPolicyByGUID(LoginState::Get()->primary_user_hash(),
525 cellular->guid(), &onc_source);
526 const NetworkPropertyUIData cellular_property_ui_data(onc_source);
527 SetValueDictionary(kTagSimCardLockEnabled,
528 new base::FundamentalValue(device->sim_lock_enabled()),
529 cellular_property_ui_data,
532 carrier_id = device->home_provider_id();
533 device_properties.GetStringWithoutPathExpansion(shill::kMdnProperty, &mdn);
535 MobileConfig* config = MobileConfig::GetInstance();
536 if (config->IsReady()) {
537 const MobileConfig::Carrier* carrier = config->GetCarrier(carrier_id);
538 if (carrier && !carrier->top_up_url().empty())
539 dictionary->SetString(kTagCarrierUrl, carrier->top_up_url());
542 base::ListValue* apn_list_value = new base::ListValue();
543 const base::ListValue* apn_list;
544 if (device_properties.GetListWithoutPathExpansion(
545 shill::kCellularApnListProperty, &apn_list)) {
546 for (base::ListValue::const_iterator iter = apn_list->begin();
547 iter != apn_list->end();
549 const base::DictionaryValue* dict;
550 if ((*iter)->GetAsDictionary(&dict)) {
551 base::DictionaryValue* apn = new base::DictionaryValue;
552 CreateDictionaryFromCellularApn(dict, apn);
553 apn_list_value->Append(apn);
557 SetValueDictionary(kTagProviderApnList,
559 cellular_property_ui_data,
561 const base::ListValue* supported_carriers;
562 if (device_properties.GetListWithoutPathExpansion(
563 shill::kSupportedCarriersProperty, &supported_carriers)) {
564 dictionary->Set(kTagCarriers, supported_carriers->DeepCopy());
565 dictionary->SetInteger(
566 kTagCurrentCarrierIndex,
567 FindCurrentCarrierIndex(supported_carriers, device));
569 // In case of any error, set the current carrier tag to -1 indicating
570 // to the JS code to fallback to a single carrier.
571 dictionary->SetInteger(kTagCurrentCarrierIndex, -1);
575 // Don't show any account management related buttons if the activation
576 // state is unknown or no payment portal URL is available.
577 std::string support_url;
578 if (cellular->activation_state() == shill::kActivationStateUnknown ||
579 !dictionary->GetString(kTagSupportUrl, &support_url) ||
580 support_url.empty()) {
581 VLOG(2) << "No support URL is available. Don't display buttons.";
585 if (cellular->activation_state() != shill::kActivationStateActivating &&
586 cellular->activation_state() != shill::kActivationStateActivated) {
587 dictionary->SetBoolean(kTagShowActivateButton, true);
589 bool may_show_portal_button = false;
591 // If an online payment URL was provided by shill, then this means that the
592 // "View Account" button should be shown for the current carrier.
595 olp->GetStringWithoutPathExpansion(shill::kPaymentPortalURL, &url);
596 may_show_portal_button = !url.empty();
598 // If no online payment URL was provided by shill, fall back to
599 // MobileConfig to determine if the "View Account" should be shown.
600 if (!may_show_portal_button && MobileConfig::GetInstance()->IsReady()) {
601 const MobileConfig::Carrier* carrier =
602 MobileConfig::GetInstance()->GetCarrier(carrier_id);
603 may_show_portal_button = carrier && carrier->show_portal_button();
605 if (may_show_portal_button) {
606 // The button should be shown for a LTE network even when the LTE network
607 // is not connected, but CrOS is online. This is done to enable users to
608 // update their plan even if they are out of credits.
609 // The button should not be shown when the device's mdn is not set,
610 // because the network's proper portal url cannot be generated without it
611 const NetworkState* default_network =
612 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
613 const std::string& technology = cellular->network_technology();
614 bool force_show_view_account_button =
615 (technology == shill::kNetworkTechnologyLte ||
616 technology == shill::kNetworkTechnologyLteAdvanced) &&
617 default_network && !mdn.empty();
619 // The button will trigger ShowMorePlanInfoCallback() which will open
620 // carrier specific portal.
621 if (cellular->IsConnectedState() || force_show_view_account_button)
622 dictionary->SetBoolean(kTagShowViewAccountButton, true);
627 scoped_ptr<base::DictionaryValue> PopulateConnectionDetails(
628 const NetworkState* network,
629 const base::DictionaryValue& shill_properties) {
630 // TODO(stevenjb): Once we eliminate all references to Shill properties,
631 // we can switch to using managed_network_configuration_handler which
632 // includes Device properties for Cellular (and skip the call to
633 // onc::TranslateShillServiceToONCPart). For now we copy them over here.
634 scoped_ptr<base::DictionaryValue> shill_properties_with_device(
635 shill_properties.DeepCopy());
636 const DeviceState* device =
637 NetworkHandler::Get()->network_state_handler()->GetDeviceState(
638 network->device_path());
640 shill_properties_with_device->SetWithoutPathExpansion(
641 shill::kDeviceProperty, device->properties().DeepCopy());
642 // Get the hardware MAC address from the DeviceState.
643 // (Note: this is done in ManagedNetworkConfigurationHandler but not
644 // in NetworkConfigurationHandler).
645 if (!device->mac_address().empty()) {
646 shill_properties_with_device->SetStringWithoutPathExpansion(
647 shill::kAddressProperty, device->mac_address());
650 scoped_ptr<base::DictionaryValue> dictionary =
651 onc::TranslateShillServiceToONCPart(
652 *shill_properties_with_device, &onc::kNetworkWithStateSignature);
654 dictionary->SetString(kNetworkInfoKeyServicePath, network->path());
655 dictionary->SetString(
657 ash::network_connect::ErrorString(network->error(), network->path()));
659 dictionary->SetBoolean(kTagRemembered, !network->profile_path().empty());
660 bool shared = !network->IsPrivate();
661 dictionary->SetBoolean(kTagShared, shared);
663 const std::string& type = network->type();
665 const NetworkState* connected_network =
666 NetworkHandler::Get()->network_state_handler()->ConnectedNetworkByType(
667 NetworkTypePattern::Primitive(type));
668 dictionary->SetBoolean(kTagDeviceConnected, connected_network != NULL);
670 if (type == shill::kTypeCellular)
671 PopulateCellularDetails(network, shill_properties, dictionary.get());
672 else if (type == shill::kTypeVPN)
673 PopulateVPNDetails(network, shill_properties, dictionary.get());
675 return dictionary.Pass();
678 // Helper methods for SetIPConfigProperties
679 bool AppendPropertyKeyIfPresent(const std::string& key,
680 const base::DictionaryValue& old_properties,
681 std::vector<std::string>* property_keys) {
682 if (old_properties.HasKey(key)) {
683 property_keys->push_back(key);
689 bool AddStringPropertyIfChanged(const std::string& key,
690 const std::string& new_value,
691 const base::DictionaryValue& old_properties,
692 base::DictionaryValue* new_properties) {
693 std::string old_value;
694 if (!old_properties.GetStringWithoutPathExpansion(key, &old_value) ||
695 new_value != old_value) {
696 new_properties->SetStringWithoutPathExpansion(key, new_value);
702 bool AddIntegerPropertyIfChanged(const std::string& key,
704 const base::DictionaryValue& old_properties,
705 base::DictionaryValue* new_properties) {
707 if (!old_properties.GetIntegerWithoutPathExpansion(key, &old_value) ||
708 new_value != old_value) {
709 new_properties->SetIntegerWithoutPathExpansion(key, new_value);
715 void RequestReconnect(const std::string& service_path,
716 gfx::NativeWindow owning_window) {
717 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
719 base::Bind(&ash::network_connect::ConnectToNetwork,
720 service_path, owning_window),
721 base::Bind(&ShillError, "RequestReconnect"));
726 InternetOptionsHandler::InternetOptionsHandler()
727 : weak_factory_(this) {
728 NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
731 InternetOptionsHandler::~InternetOptionsHandler() {
732 if (NetworkHandler::IsInitialized()) {
733 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
738 void InternetOptionsHandler::GetLocalizedValues(
739 base::DictionaryValue* localized_strings) {
740 DCHECK(localized_strings);
741 internet_options_strings::RegisterLocalizedStrings(localized_strings);
743 // TODO(stevenjb): Find a better way to populate initial data before
744 // InitializePage() gets called.
746 chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
747 localized_strings->SetString("ownerUserId", base::UTF8ToUTF16(owner));
748 bool logged_in_as_owner = LoginState::Get()->GetLoggedInUserType() ==
749 LoginState::LOGGED_IN_USER_OWNER;
750 localized_strings->SetBoolean("loggedInAsOwner", logged_in_as_owner);
752 base::DictionaryValue* network_dictionary = new base::DictionaryValue;
753 FillNetworkInfo(network_dictionary);
754 localized_strings->Set("networkData", network_dictionary);
757 void InternetOptionsHandler::InitializePage() {
758 base::DictionaryValue dictionary;
759 dictionary.SetString(::onc::network_type::kCellular,
760 GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK));
761 dictionary.SetString(::onc::network_type::kWiFi,
762 GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK));
763 dictionary.SetString(::onc::network_type::kVPN,
764 GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_VPN));
765 web_ui()->CallJavascriptFunction(kSetDefaultNetworkIconsFunction,
767 NetworkHandler::Get()->network_state_handler()->RequestScan();
768 RefreshNetworkData();
771 void InternetOptionsHandler::RegisterMessages() {
772 // Setup handlers specific to this panel.
773 web_ui()->RegisterMessageCallback(kNetworkCommandMessage,
774 base::Bind(&InternetOptionsHandler::NetworkCommandCallback,
775 base::Unretained(this)));
776 web_ui()->RegisterMessageCallback(kRefreshNetworksMessage,
777 base::Bind(&InternetOptionsHandler::RefreshNetworksCallback,
778 base::Unretained(this)));
779 web_ui()->RegisterMessageCallback(kSetPreferNetworkMessage,
780 base::Bind(&InternetOptionsHandler::SetPreferNetworkCallback,
781 base::Unretained(this)));
782 web_ui()->RegisterMessageCallback(kSetAutoConnectMessage,
783 base::Bind(&InternetOptionsHandler::SetAutoConnectCallback,
784 base::Unretained(this)));
785 web_ui()->RegisterMessageCallback(kSetIPConfigMessage,
786 base::Bind(&InternetOptionsHandler::SetIPConfigCallback,
787 base::Unretained(this)));
788 web_ui()->RegisterMessageCallback(kEnableWifiMessage,
789 base::Bind(&InternetOptionsHandler::EnableWifiCallback,
790 base::Unretained(this)));
791 web_ui()->RegisterMessageCallback(kDisableWifiMessage,
792 base::Bind(&InternetOptionsHandler::DisableWifiCallback,
793 base::Unretained(this)));
794 web_ui()->RegisterMessageCallback(kEnableCellularMessage,
795 base::Bind(&InternetOptionsHandler::EnableCellularCallback,
796 base::Unretained(this)));
797 web_ui()->RegisterMessageCallback(kDisableCellularMessage,
798 base::Bind(&InternetOptionsHandler::DisableCellularCallback,
799 base::Unretained(this)));
800 web_ui()->RegisterMessageCallback(kEnableWimaxMessage,
801 base::Bind(&InternetOptionsHandler::EnableWimaxCallback,
802 base::Unretained(this)));
803 web_ui()->RegisterMessageCallback(kDisableWimaxMessage,
804 base::Bind(&InternetOptionsHandler::DisableWimaxCallback,
805 base::Unretained(this)));
806 web_ui()->RegisterMessageCallback(kBuyDataPlanMessage,
807 base::Bind(&InternetOptionsHandler::BuyDataPlanCallback,
808 base::Unretained(this)));
809 web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage,
810 base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback,
811 base::Unretained(this)));
812 web_ui()->RegisterMessageCallback(kSetApnMessage,
813 base::Bind(&InternetOptionsHandler::SetApnCallback,
814 base::Unretained(this)));
815 web_ui()->RegisterMessageCallback(kSetCarrierMessage,
816 base::Bind(&InternetOptionsHandler::SetCarrierCallback,
817 base::Unretained(this)));
818 web_ui()->RegisterMessageCallback(kSetSimCardLockMessage,
819 base::Bind(&InternetOptionsHandler::SetSimCardLockCallback,
820 base::Unretained(this)));
821 web_ui()->RegisterMessageCallback(kChangePinMessage,
822 base::Bind(&InternetOptionsHandler::ChangePinCallback,
823 base::Unretained(this)));
824 web_ui()->RegisterMessageCallback(kSetServerHostname,
825 base::Bind(&InternetOptionsHandler::SetServerHostnameCallback,
826 base::Unretained(this)));
829 void InternetOptionsHandler::EnableWifiCallback(const base::ListValue* args) {
830 content::RecordAction(base::UserMetricsAction("Options_NetworkWifiToggle"));
831 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
832 NetworkTypePattern::WiFi(), true,
833 base::Bind(&ShillError, "EnableWifiCallback"));
836 void InternetOptionsHandler::DisableWifiCallback(const base::ListValue* args) {
837 content::RecordAction(base::UserMetricsAction("Options_NetworkWifiToggle"));
838 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
839 NetworkTypePattern::WiFi(), false,
840 base::Bind(&ShillError, "DisableWifiCallback"));
843 void InternetOptionsHandler::EnableCellularCallback(
844 const base::ListValue* args) {
845 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
846 const DeviceState* device =
847 handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
849 LOG(ERROR) << "Mobile device not found.";
852 if (!device->sim_lock_type().empty()) {
853 SimDialogDelegate::ShowDialog(GetNativeWindow(),
854 SimDialogDelegate::SIM_DIALOG_UNLOCK);
857 if (!handler->IsTechnologyEnabled(NetworkTypePattern::Cellular())) {
858 handler->SetTechnologyEnabled(
859 NetworkTypePattern::Cellular(), true,
860 base::Bind(&ShillError, "EnableCellularCallback"));
863 if (device->IsSimAbsent()) {
864 mobile_config_ui::DisplayConfigDialog();
867 LOG(ERROR) << "EnableCellularCallback called for enabled mobile device";
870 void InternetOptionsHandler::DisableCellularCallback(
871 const base::ListValue* args) {
872 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
873 NetworkTypePattern::Mobile(), false,
874 base::Bind(&ShillError, "DisableCellularCallback"));
877 void InternetOptionsHandler::EnableWimaxCallback(const base::ListValue* args) {
878 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
879 NetworkTypePattern::Wimax(), true,
880 base::Bind(&ShillError, "EnableWimaxCallback"));
883 void InternetOptionsHandler::DisableWimaxCallback(const base::ListValue* args) {
884 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
885 NetworkTypePattern::Wimax(), false,
886 base::Bind(&ShillError, "DisableWimaxCallback"));
889 void InternetOptionsHandler::ShowMorePlanInfoCallback(
890 const base::ListValue* args) {
893 std::string service_path;
894 if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
898 ash::network_connect::ShowMobileSetup(service_path);
901 void InternetOptionsHandler::BuyDataPlanCallback(const base::ListValue* args) {
904 std::string service_path;
905 if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
909 ash::network_connect::ShowMobileSetup(service_path);
912 void InternetOptionsHandler::SetApnCallback(const base::ListValue* args) {
913 std::string service_path;
914 if (!args->GetString(0, &service_path)) {
918 NetworkHandler::Get()->network_configuration_handler()->GetProperties(
920 base::Bind(&InternetOptionsHandler::SetApnProperties,
921 weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
922 base::Bind(&ShillError, "SetApnCallback"));
925 void InternetOptionsHandler::SetApnProperties(
926 const base::ListValue* args,
927 const std::string& service_path,
928 const base::DictionaryValue& shill_properties) {
929 std::string apn, username, password;
930 if (!args->GetString(1, &apn) ||
931 !args->GetString(2, &username) ||
932 !args->GetString(3, &password)) {
936 NET_LOG_EVENT("SetApnCallback", service_path);
939 std::vector<std::string> properties_to_clear;
940 properties_to_clear.push_back(shill::kCellularApnProperty);
941 NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
942 service_path, properties_to_clear,
943 base::Bind(&base::DoNothing),
944 base::Bind(&ShillError, "ClearCellularApnProperties"));
948 const base::DictionaryValue* shill_apn_dict = NULL;
949 std::string network_id;
950 if (shill_properties.GetDictionaryWithoutPathExpansion(
951 shill::kCellularApnProperty, &shill_apn_dict)) {
952 shill_apn_dict->GetStringWithoutPathExpansion(
953 shill::kApnNetworkIdProperty, &network_id);
955 base::DictionaryValue properties;
956 base::DictionaryValue* apn_dict = new base::DictionaryValue;
957 apn_dict->SetStringWithoutPathExpansion(shill::kApnProperty, apn);
958 apn_dict->SetStringWithoutPathExpansion(shill::kApnNetworkIdProperty,
960 apn_dict->SetStringWithoutPathExpansion(shill::kApnUsernameProperty,
962 apn_dict->SetStringWithoutPathExpansion(shill::kApnPasswordProperty,
964 properties.SetWithoutPathExpansion(shill::kCellularApnProperty, apn_dict);
965 NetworkHandler::Get()->network_configuration_handler()->SetProperties(
966 service_path, properties,
967 base::Bind(&base::DoNothing),
968 base::Bind(&ShillError, "SetApnProperties"));
971 void InternetOptionsHandler::CarrierStatusCallback() {
972 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
973 const DeviceState* device =
974 handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
975 if (device && (device->carrier() == shill::kCarrierSprint)) {
976 const NetworkState* network =
977 handler->FirstNetworkByType(NetworkTypePattern::Cellular());
979 ash::network_connect::ActivateCellular(network->path());
980 UpdateConnectionData(network->path());
986 void InternetOptionsHandler::SetCarrierCallback(const base::ListValue* args) {
987 std::string service_path;
989 if (args->GetSize() != 2 ||
990 !args->GetString(0, &service_path) ||
991 !args->GetString(1, &carrier)) {
995 const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
996 GetDeviceStateByType(NetworkTypePattern::Cellular());
998 LOG(WARNING) << "SetCarrierCallback with no cellular device.";
1001 NetworkHandler::Get()->network_device_handler()->SetCarrier(
1004 base::Bind(&InternetOptionsHandler::CarrierStatusCallback,
1005 weak_factory_.GetWeakPtr()),
1006 base::Bind(&ShillError, "SetCarrierCallback"));
1009 void InternetOptionsHandler::SetSimCardLockCallback(
1010 const base::ListValue* args) {
1011 bool require_pin_new_value;
1012 if (!args->GetBoolean(0, &require_pin_new_value)) {
1016 // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL.
1017 // 2. Dialog will ask for current PIN in any case.
1018 // 3. If card is locked it will first call PIN unlock operation
1019 // 4. Then it will call Set RequirePin, passing the same PIN.
1020 // 5. The dialog may change device properties, in which case
1021 // DevicePropertiesUpdated() will get called which will update the UI.
1022 SimDialogDelegate::SimDialogMode mode;
1023 if (require_pin_new_value)
1024 mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON;
1026 mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF;
1027 SimDialogDelegate::ShowDialog(GetNativeWindow(), mode);
1030 void InternetOptionsHandler::ChangePinCallback(const base::ListValue* args) {
1031 SimDialogDelegate::ShowDialog(GetNativeWindow(),
1032 SimDialogDelegate::SIM_DIALOG_CHANGE_PIN);
1035 void InternetOptionsHandler::RefreshNetworksCallback(
1036 const base::ListValue* args) {
1037 NetworkHandler::Get()->network_state_handler()->RequestScan();
1040 std::string InternetOptionsHandler::GetIconDataUrl(int resource_id) const {
1041 gfx::ImageSkia* icon =
1042 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
1043 gfx::ImageSkiaRep image_rep = icon->GetRepresentation(
1044 web_ui()->GetDeviceScaleFactor());
1045 return webui::GetBitmapDataUrl(image_rep.sk_bitmap());
1048 void InternetOptionsHandler::RefreshNetworkData() {
1049 base::DictionaryValue dictionary;
1050 FillNetworkInfo(&dictionary);
1051 web_ui()->CallJavascriptFunction(kRefreshNetworkDataFunction, dictionary);
1054 void InternetOptionsHandler::UpdateConnectionData(
1055 const std::string& service_path) {
1056 NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1058 base::Bind(&InternetOptionsHandler::UpdateConnectionDataCallback,
1059 weak_factory_.GetWeakPtr()),
1060 base::Bind(&ShillError, "UpdateConnectionData"));
1063 void InternetOptionsHandler::UpdateConnectionDataCallback(
1064 const std::string& service_path,
1065 const base::DictionaryValue& shill_properties) {
1066 const NetworkState* network = GetNetworkState(service_path);
1069 scoped_ptr<base::DictionaryValue> dictionary =
1070 PopulateConnectionDetails(network, shill_properties);
1071 web_ui()->CallJavascriptFunction(kUpdateConnectionDataFunction, *dictionary);
1074 void InternetOptionsHandler::UpdateCarrier() {
1075 web_ui()->CallJavascriptFunction(kUpdateCarrierFunction);
1078 void InternetOptionsHandler::DeviceListChanged() {
1081 RefreshNetworkData();
1084 void InternetOptionsHandler::NetworkListChanged() {
1087 RefreshNetworkData();
1090 void InternetOptionsHandler::NetworkConnectionStateChanged(
1091 const NetworkState* network) {
1094 // Update the connection data for the detailed view when the connection state
1095 // of any network changes.
1096 if (!details_path_.empty())
1097 UpdateConnectionData(details_path_);
1100 void InternetOptionsHandler::NetworkPropertiesUpdated(
1101 const NetworkState* network) {
1104 RefreshNetworkData();
1105 UpdateConnectionData(network->path());
1108 void InternetOptionsHandler::DevicePropertiesUpdated(
1109 const DeviceState* device) {
1112 if (device->type() != shill::kTypeCellular)
1114 const NetworkState* network =
1115 NetworkHandler::Get()->network_state_handler()->FirstNetworkByType(
1116 NetworkTypePattern::Cellular());
1118 UpdateConnectionData(network->path()); // Update sim lock status.
1121 void InternetOptionsHandler::SetServerHostnameCallback(
1122 const base::ListValue* args) {
1123 std::string service_path, server_hostname;
1124 if (args->GetSize() < 2 ||
1125 !args->GetString(0, &service_path) ||
1126 !args->GetString(1, &server_hostname)) {
1130 SetNetworkProperty(service_path,
1131 shill::kProviderHostProperty,
1132 new base::StringValue(server_hostname));
1135 void InternetOptionsHandler::SetPreferNetworkCallback(
1136 const base::ListValue* args) {
1137 std::string service_path, prefer_network_str;
1138 if (args->GetSize() < 2 ||
1139 !args->GetString(0, &service_path) ||
1140 !args->GetString(1, &prefer_network_str)) {
1144 content::RecordAction(base::UserMetricsAction("Options_NetworkSetPrefer"));
1145 int priority = (prefer_network_str == kTagTrue) ? kPreferredPriority : 0;
1146 SetNetworkProperty(service_path,
1147 shill::kPriorityProperty,
1148 new base::FundamentalValue(priority));
1151 void InternetOptionsHandler::SetAutoConnectCallback(
1152 const base::ListValue* args) {
1153 std::string service_path, auto_connect_str;
1154 if (args->GetSize() < 2 ||
1155 !args->GetString(0, &service_path) ||
1156 !args->GetString(1, &auto_connect_str)) {
1160 content::RecordAction(base::UserMetricsAction("Options_NetworkAutoConnect"));
1161 bool auto_connect = auto_connect_str == kTagTrue;
1162 SetNetworkProperty(service_path,
1163 shill::kAutoConnectProperty,
1164 new base::FundamentalValue(auto_connect));
1167 void InternetOptionsHandler::SetIPConfigCallback(const base::ListValue* args) {
1168 std::string service_path;
1169 if (!args->GetString(0, &service_path)) {
1173 NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1175 base::Bind(&InternetOptionsHandler::SetIPConfigProperties,
1176 weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
1177 base::Bind(&ShillError, "SetIPConfigCallback"));
1180 void InternetOptionsHandler::SetIPConfigProperties(
1181 const base::ListValue* args,
1182 const std::string& service_path,
1183 const base::DictionaryValue& shill_properties) {
1184 std::string address, netmask, gateway, name_server_type, name_servers;
1186 if (!args->GetBoolean(1, &dhcp_for_ip) ||
1187 !args->GetString(2, &address) ||
1188 !args->GetString(3, &netmask) ||
1189 !args->GetString(4, &gateway) ||
1190 !args->GetString(5, &name_server_type) ||
1191 !args->GetString(6, &name_servers)) {
1195 NET_LOG_USER("SetIPConfigProperties", service_path);
1197 bool request_reconnect = false;
1198 std::vector<std::string> properties_to_clear;
1199 base::DictionaryValue properties_to_set;
1202 request_reconnect |= AppendPropertyKeyIfPresent(
1203 shill::kStaticIPAddressProperty,
1204 shill_properties, &properties_to_clear);
1205 request_reconnect |= AppendPropertyKeyIfPresent(
1206 shill::kStaticIPPrefixlenProperty,
1207 shill_properties, &properties_to_clear);
1208 request_reconnect |= AppendPropertyKeyIfPresent(
1209 shill::kStaticIPGatewayProperty,
1210 shill_properties, &properties_to_clear);
1212 request_reconnect |= AddStringPropertyIfChanged(
1213 shill::kStaticIPAddressProperty,
1214 address, shill_properties, &properties_to_set);
1215 int prefixlen = network_util::NetmaskToPrefixLength(netmask);
1216 if (prefixlen < 0) {
1217 LOG(ERROR) << "Invalid prefix length for: " << service_path
1218 << " with netmask " << netmask;
1221 request_reconnect |= AddIntegerPropertyIfChanged(
1222 shill::kStaticIPPrefixlenProperty,
1223 prefixlen, shill_properties, &properties_to_set);
1224 request_reconnect |= AddStringPropertyIfChanged(
1225 shill::kStaticIPGatewayProperty,
1226 gateway, shill_properties, &properties_to_set);
1229 if (name_server_type == kNameServerTypeAutomatic) {
1230 AppendPropertyKeyIfPresent(shill::kStaticIPNameServersProperty,
1231 shill_properties, &properties_to_clear);
1233 if (name_server_type == kNameServerTypeGoogle)
1234 name_servers = kGoogleNameServers;
1235 AddStringPropertyIfChanged(
1236 shill::kStaticIPNameServersProperty,
1237 name_servers, shill_properties, &properties_to_set);
1240 if (!properties_to_clear.empty()) {
1241 NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
1242 service_path, properties_to_clear,
1243 base::Bind(&base::DoNothing),
1244 base::Bind(&ShillError, "ClearIPConfigProperties"));
1246 if (!properties_to_set.empty()) {
1247 NetworkHandler::Get()->network_configuration_handler()->SetProperties(
1248 service_path, properties_to_set,
1249 base::Bind(&base::DoNothing),
1250 base::Bind(&ShillError, "SetIPConfigProperties"));
1252 std::string device_path;
1253 shill_properties.GetStringWithoutPathExpansion(
1254 shill::kDeviceProperty, &device_path);
1255 if (!device_path.empty()) {
1256 base::Closure callback = base::Bind(&base::DoNothing);
1257 // If auto config or a static IP property changed, we need to reconnect
1259 if (request_reconnect)
1260 callback = base::Bind(&RequestReconnect, service_path, GetNativeWindow());
1261 NetworkHandler::Get()->network_device_handler()->RequestRefreshIPConfigs(
1264 base::Bind(&ShillError, "RequestRefreshIPConfigs"));
1268 void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
1269 const std::string& service_path,
1270 const base::DictionaryValue& shill_properties) {
1271 const NetworkState* network = GetNetworkState(service_path);
1273 LOG(ERROR) << "Network properties not found: " << service_path;
1277 details_path_ = service_path;
1279 scoped_ptr<base::DictionaryValue> dictionary =
1280 PopulateConnectionDetails(network, shill_properties);
1282 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
1283 const base::DictionaryValue* onc =
1284 onc::FindPolicyForActiveUser(network->guid(), &onc_source);
1285 const NetworkPropertyUIData property_ui_data(onc_source);
1288 scoped_ptr<base::DictionaryValue> ipconfig_dhcp(new base::DictionaryValue);
1289 ipconfig_dhcp->SetString(kIpConfigAddress, network->ip_address());
1290 ipconfig_dhcp->SetString(kIpConfigNetmask, network->GetNetmask());
1291 ipconfig_dhcp->SetString(kIpConfigGateway, network->gateway());
1292 std::string ipconfig_name_servers = network->GetDnsServersAsString();
1293 ipconfig_dhcp->SetString(kIpConfigNameServers, ipconfig_name_servers);
1294 ipconfig_dhcp->SetString(kIpConfigWebProxyAutoDiscoveryUrl,
1295 network->web_proxy_auto_discovery_url().spec());
1296 SetValueDictionary(kDictionaryIpConfig,
1297 ipconfig_dhcp.release(),
1301 std::string name_server_type = kNameServerTypeAutomatic;
1302 int automatic_ip_config = 0;
1303 scoped_ptr<base::DictionaryValue> static_ip_dict(
1304 BuildIPInfoDictionary(shill_properties, true, &automatic_ip_config));
1305 dictionary->SetBoolean(kIpConfigAutoConfig, automatic_ip_config == 0);
1306 DCHECK(automatic_ip_config == 3 || automatic_ip_config == 0)
1307 << "UI doesn't support automatic specification of individual "
1308 << "static IP parameters.";
1309 scoped_ptr<base::DictionaryValue> saved_ip_dict(
1310 BuildIPInfoDictionary(shill_properties, false, NULL));
1311 dictionary->Set(kDictionarySavedIp, saved_ip_dict.release());
1313 // Determine what kind of name server setting we have by comparing the
1314 // StaticIP and Google values with the ipconfig values.
1315 std::string static_ip_nameservers;
1316 static_ip_dict->GetString(kIpConfigNameServers, &static_ip_nameservers);
1317 if (!static_ip_nameservers.empty() &&
1318 static_ip_nameservers == ipconfig_name_servers) {
1319 name_server_type = kNameServerTypeUser;
1321 if (ipconfig_name_servers == kGoogleNameServers) {
1322 name_server_type = kNameServerTypeGoogle;
1324 SetValueDictionary(kDictionaryStaticIp,
1325 static_ip_dict.release(),
1329 dictionary->SetString(kTagNameServerType, name_server_type);
1330 dictionary->SetString(kTagNameServersGoogle, kGoogleNameServers);
1333 shill_properties.GetIntegerWithoutPathExpansion(
1334 shill::kPriorityProperty, &priority);
1335 bool preferred = priority > 0;
1336 SetValueDictionary(kTagPreferred,
1337 new base::FundamentalValue(preferred),
1341 std::string onc_path_to_auto_connect;
1342 if (network->Matches(NetworkTypePattern::WiFi())) {
1343 content::RecordAction(
1344 base::UserMetricsAction("Options_NetworkShowDetailsWifi"));
1345 if (network->IsConnectedState()) {
1346 content::RecordAction(
1347 base::UserMetricsAction("Options_NetworkShowDetailsWifiConnected"));
1349 onc_path_to_auto_connect =
1350 ::onc::network_config::WifiProperty(::onc::wifi::kAutoConnect);
1351 } else if (network->Matches(NetworkTypePattern::VPN())) {
1352 content::RecordAction(
1353 base::UserMetricsAction("Options_NetworkShowDetailsVPN"));
1354 if (network->IsConnectedState()) {
1355 content::RecordAction(
1356 base::UserMetricsAction("Options_NetworkShowDetailsVPNConnected"));
1358 onc_path_to_auto_connect = ::onc::network_config::VpnProperty(
1359 ::onc::vpn::kAutoConnect);
1360 } else if (network->Matches(NetworkTypePattern::Cellular())) {
1361 content::RecordAction(
1362 base::UserMetricsAction("Options_NetworkShowDetailsCellular"));
1363 if (network->IsConnectedState()) {
1364 content::RecordAction(base::UserMetricsAction(
1365 "Options_NetworkShowDetailsCellularConnected"));
1369 if (!onc_path_to_auto_connect.empty()) {
1370 bool auto_connect = false;
1371 shill_properties.GetBooleanWithoutPathExpansion(
1372 shill::kAutoConnectProperty, &auto_connect);
1374 scoped_ptr<base::Value> auto_connect_value(
1375 new base::FundamentalValue(auto_connect));
1376 ::onc::ONCSource auto_connect_onc_source = onc_source;
1378 DCHECK_EQ(onc == NULL, onc_source == ::onc::ONC_SOURCE_NONE);
1379 bool auto_connect_recommended =
1380 auto_connect_onc_source != ::onc::ONC_SOURCE_NONE &&
1381 onc::IsRecommendedValue(onc, onc_path_to_auto_connect);
1382 // If a policy exists, |auto_connect_default_value| will contain either a
1383 // recommended value (if |auto_connect_recommended| is true) or an enforced
1384 // value (if |auto_connect_recommended| is false).
1385 const base::Value* auto_connect_default_value = NULL;
1387 onc->Get(onc_path_to_auto_connect, &auto_connect_default_value);
1389 // Autoconnect can be controlled by the GlobalNetworkConfiguration of the
1391 if (auto_connect_onc_source == ::onc::ONC_SOURCE_NONE &&
1392 onc::PolicyAllowsOnlyPolicyNetworksToAutoconnect(
1393 network->IsPrivate())) {
1394 auto_connect_recommended = false;
1395 auto_connect_onc_source = network->IsPrivate()
1396 ? ::onc::ONC_SOURCE_USER_POLICY
1397 : ::onc::ONC_SOURCE_DEVICE_POLICY;
1399 LOG(WARNING) << "Policy prevents autoconnect, but value is True.";
1400 auto_connect_value.reset(new base::FundamentalValue(false));
1403 SetManagedValueDictionary(shill::kAutoConnectProperty,
1404 auto_connect_value.get(),
1405 auto_connect_onc_source,
1406 auto_connect_recommended,
1407 auto_connect_default_value,
1411 // Show details dialog
1412 web_ui()->CallJavascriptFunction(kShowDetailedInfoFunction, *dictionary);
1415 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
1416 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
1419 float InternetOptionsHandler::GetScaleFactor() const {
1420 return web_ui()->GetDeviceScaleFactor();
1423 const PrefService* InternetOptionsHandler::GetPrefs() const {
1424 return Profile::FromWebUI(web_ui())->GetPrefs();
1427 void InternetOptionsHandler::NetworkCommandCallback(
1428 const base::ListValue* args) {
1429 std::string onc_type;
1430 std::string service_path;
1431 std::string command;
1432 if (args->GetSize() != 3 ||
1433 !args->GetString(0, &onc_type) ||
1434 !args->GetString(1, &service_path) ||
1435 !args->GetString(2, &command)) {
1439 std::string type; // Shill type
1440 if (!onc_type.empty()) {
1441 type = network_util::TranslateONCTypeToShill(onc_type);
1443 LOG(ERROR) << "Unable to translate ONC type: " << onc_type;
1445 // Process commands that do not require an existing network.
1446 if (command == kTagAddConnection) {
1447 AddConnection(type);
1448 } else if (command == kTagForget) {
1449 NetworkHandler::Get()->network_configuration_handler()->
1450 RemoveConfiguration(
1452 base::Bind(&base::DoNothing),
1453 base::Bind(&ShillError, "NetworkCommand: " + command));
1454 } else if (command == kTagOptions) {
1455 NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1457 base::Bind(&InternetOptionsHandler::PopulateDictionaryDetailsCallback,
1458 weak_factory_.GetWeakPtr()),
1459 base::Bind(&ShillError, "NetworkCommand: " + command));
1460 } else if (command == kTagConnect) {
1461 const NetworkState* network = GetNetworkState(service_path);
1462 if (network && network->type() == shill::kTypeWifi)
1463 content::RecordAction(
1464 base::UserMetricsAction("Options_NetworkConnectToWifi"));
1465 else if (network && network->type() == shill::kTypeVPN)
1466 content::RecordAction(
1467 base::UserMetricsAction("Options_NetworkConnectToVPN"));
1468 ash::network_connect::ConnectToNetwork(service_path, GetNativeWindow());
1469 } else if (command == kTagDisconnect) {
1470 const NetworkState* network = GetNetworkState(service_path);
1471 if (network && network->type() == shill::kTypeWifi)
1472 content::RecordAction(
1473 base::UserMetricsAction("Options_NetworkDisconnectWifi"));
1474 else if (network && network->type() == shill::kTypeVPN)
1475 content::RecordAction(
1476 base::UserMetricsAction("Options_NetworkDisconnectVPN"));
1477 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
1479 base::Bind(&base::DoNothing),
1480 base::Bind(&ShillError, "NetworkCommand: " + command));
1481 } else if (command == kTagConfigure) {
1482 NetworkConfigView::Show(service_path, GetNativeWindow());
1483 } else if (command == kTagActivate && type == shill::kTypeCellular) {
1484 ash::network_connect::ActivateCellular(service_path);
1485 // Activation may update network properties (e.g. ActivationState), so
1486 // request them here in case they change.
1487 UpdateConnectionData(service_path);
1489 VLOG(1) << "Unknown command: " << command;
1494 void InternetOptionsHandler::AddConnection(const std::string& type) {
1495 if (type == shill::kTypeWifi) {
1496 content::RecordAction(
1497 base::UserMetricsAction("Options_NetworkJoinOtherWifi"));
1498 NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow());
1499 } else if (type == shill::kTypeVPN) {
1500 content::RecordAction(
1501 base::UserMetricsAction("Options_NetworkJoinOtherVPN"));
1502 NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow());
1503 } else if (type == shill::kTypeCellular) {
1504 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
1506 LOG(ERROR) << "Unsupported type for AddConnection";
1510 base::ListValue* InternetOptionsHandler::GetWiredList() {
1511 base::ListValue* list = new base::ListValue();
1512 const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
1513 FirstNetworkByType(NetworkTypePattern::Ethernet());
1516 list->Append(BuildNetworkDictionary(network, GetScaleFactor(), GetPrefs()));
1520 base::ListValue* InternetOptionsHandler::GetWirelessList() {
1521 base::ListValue* list = new base::ListValue();
1523 NetworkStateHandler::NetworkStateList networks;
1524 NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
1525 NetworkTypePattern::Wireless(), &networks);
1526 for (NetworkStateHandler::NetworkStateList::const_iterator iter =
1527 networks.begin(); iter != networks.end(); ++iter) {
1528 list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs()));
1534 base::ListValue* InternetOptionsHandler::GetVPNList() {
1535 base::ListValue* list = new base::ListValue();
1537 NetworkStateHandler::NetworkStateList networks;
1538 NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
1539 NetworkTypePattern::VPN(), &networks);
1540 for (NetworkStateHandler::NetworkStateList::const_iterator iter =
1541 networks.begin(); iter != networks.end(); ++iter) {
1542 list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs()));
1548 base::ListValue* InternetOptionsHandler::GetRememberedList() {
1549 base::ListValue* list = new base::ListValue();
1551 NetworkStateHandler::NetworkStateList networks;
1552 NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
1553 NetworkTypePattern::Default(),
1554 true /* configured_only */,
1555 false /* visible_only */,
1558 for (NetworkStateHandler::NetworkStateList::const_iterator iter =
1559 networks.begin(); iter != networks.end(); ++iter) {
1560 const NetworkState* network = *iter;
1561 if (network->type() != shill::kTypeWifi &&
1562 network->type() != shill::kTypeVPN)
1565 BuildNetworkDictionary(network,
1566 web_ui()->GetDeviceScaleFactor(),
1567 Profile::FromWebUI(web_ui())->GetPrefs()));
1573 void InternetOptionsHandler::FillNetworkInfo(
1574 base::DictionaryValue* dictionary) {
1575 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
1576 dictionary->Set(kTagWiredList, GetWiredList());
1577 dictionary->Set(kTagWirelessList, GetWirelessList());
1578 dictionary->Set(kTagVpnList, GetVPNList());
1579 dictionary->Set(kTagRememberedList, GetRememberedList());
1581 dictionary->SetBoolean(
1583 handler->IsTechnologyAvailable(NetworkTypePattern::WiFi()));
1584 dictionary->SetBoolean(
1586 handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()));
1588 dictionary->SetBoolean(
1589 kTagCellularAvailable,
1590 handler->IsTechnologyAvailable(NetworkTypePattern::Mobile()));
1591 dictionary->SetBoolean(
1592 kTagCellularEnabled,
1593 handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()));
1594 const DeviceState* cellular =
1595 handler->GetDeviceStateByType(NetworkTypePattern::Mobile());
1596 dictionary->SetBoolean(
1597 kTagCellularSupportsScan,
1598 cellular && cellular->support_network_scan());
1600 dictionary->SetBoolean(
1602 handler->IsTechnologyAvailable(NetworkTypePattern::Wimax()));
1603 dictionary->SetBoolean(
1605 handler->IsTechnologyEnabled(NetworkTypePattern::Wimax()));
1608 } // namespace options
1609 } // namespace chromeos