Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / options / chromeos / internet_options_handler.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
6
7 #include <ctype.h>
8
9 #include <map>
10 #include <string>
11 #include <vector>
12
13 #include "ash/system/chromeos/network/network_connect.h"
14 #include "base/basictypes.h"
15 #include "base/bind.h"
16 #include "base/bind_helpers.h"
17 #include "base/command_line.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chromeos/mobile_config.h"
22 #include "chrome/browser/chromeos/net/onc_utils.h"
23 #include "chrome/browser/chromeos/options/network_config_view.h"
24 #include "chrome/browser/chromeos/options/network_property_ui_data.h"
25 #include "chrome/browser/chromeos/settings/cros_settings.h"
26 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
27 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
28 #include "chrome/browser/chromeos/ui/mobile_config_ui.h"
29 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h"
32 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h"
33 #include "chromeos/chromeos_switches.h"
34 #include "chromeos/login/login_state.h"
35 #include "chromeos/network/device_state.h"
36 #include "chromeos/network/managed_network_configuration_handler.h"
37 #include "chromeos/network/network_configuration_handler.h"
38 #include "chromeos/network/network_connection_handler.h"
39 #include "chromeos/network/network_device_handler.h"
40 #include "chromeos/network/network_event_log.h"
41 #include "chromeos/network/network_ip_config.h"
42 #include "chromeos/network/network_profile.h"
43 #include "chromeos/network/network_profile_handler.h"
44 #include "chromeos/network/network_state.h"
45 #include "chromeos/network/network_state_handler.h"
46 #include "chromeos/network/network_util.h"
47 #include "chromeos/network/onc/onc_signature.h"
48 #include "chromeos/network/onc/onc_translation_tables.h"
49 #include "chromeos/network/onc/onc_translator.h"
50 #include "chromeos/network/onc/onc_utils.h"
51 #include "components/onc/onc_constants.h"
52 #include "content/public/browser/web_contents.h"
53 #include "content/public/browser/web_ui.h"
54 #include "grit/ui_chromeos_resources.h"
55 #include "third_party/cros_system_api/dbus/service_constants.h"
56 #include "ui/base/resource/resource_bundle.h"
57 #include "ui/base/webui/web_ui_util.h"
58 #include "ui/chromeos/network/network_icon.h"
59 #include "ui/gfx/image/image_skia.h"
60
61 namespace chromeos {
62 namespace options {
63
64 namespace {
65
66 // Keys for the network description dictionary passed to the web ui. Make sure
67 // to keep the strings in sync with what the JavaScript side uses.
68 const char kNetworkInfoKeyIconURL[] = "iconURL";
69 const char kNetworkInfoKeyPolicyManaged[] = "policyManaged";
70
71 // These are types of name server selections from the web ui.
72 const char kNameServerTypeAutomatic[] = "automatic";
73 const char kNameServerTypeGoogle[] = "google";
74
75 // Google public name servers (DNS).
76 const char kGoogleNameServers[] = "8.8.4.4,8.8.8.8";
77
78 // Functions we call in JavaScript.
79 const char kRefreshNetworkDataFunction[] =
80     "options.network.NetworkList.refreshNetworkData";
81 const char kSetDefaultNetworkIconsFunction[] =
82     "options.network.NetworkList.setDefaultNetworkIcons";
83 const char kSendNetworkDetailsFunction[] =
84     "options.internet.DetailsInternetPage.sendNetworkDetails";
85 const char kShowDetailedInfoFunction[] =
86     "options.internet.DetailsInternetPage.showDetailedInfo";
87 const char kUpdateConnectionDataFunction[] =
88     "options.internet.DetailsInternetPage.updateConnectionData";
89 const char kUpdateCarrierFunction[] =
90     "options.internet.DetailsInternetPage.updateCarrier";
91
92 // These are used to register message handlers with JavaScript.
93 const char kNetworkCommandMessage[] = "networkCommand";
94 const char kSetApnMessage[] = "setApn";
95 const char kSetAutoConnectMessage[] = "setAutoConnect";
96 const char kSetCarrierMessage[] = "setCarrier";
97 const char kSetIPConfigMessage[] = "setIPConfig";
98 const char kSetPreferNetworkMessage[] = "setPreferNetwork";
99 const char kSetServerHostname[] = "setServerHostname";
100 const char kShowMorePlanInfoMessage[] = "showMorePlanInfo";
101 const char kSimOperationMessage[] = "simOperation";
102
103 // TODO(stevenjb): Replace these with the matching networkingPrivate methods.
104 // crbug.com/279351.
105 const char kDisableNetworkTypeMessage[] = "disableNetworkType";
106 const char kEnableNetworkTypeMessage[] = "enableNetworkType";
107 const char kGetManagedPropertiesMessage[] = "getManagedProperties";
108 const char kRequestNetworkScanMessage[] = "requestNetworkScan";
109 const char kStartConnectMessage[] = "startConnect";
110 const char kStartDisconnectMessage[] = "startDisconnect";
111
112 // These are strings used to communicate with JavaScript.
113 const char kTagActivate[] = "activate";
114 const char kTagAddConnection[] = "add";
115 const char kTagCarrierSelectFlag[] = "showCarrierSelect";
116 const char kTagCellularAvailable[] = "cellularAvailable";
117 const char kTagCellularEnabled[] = "cellularEnabled";
118 const char kTagCellularSimAbsent[] = "cellularSimAbsent";
119 const char kTagCellularSimLockType[] = "cellularSimLockType";
120 const char kTagCellularSupportsScan[] = "cellularSupportsScan";
121 const char kTagConfigure[] = "configure";
122 const char kTagForget[] = "forget";
123 const char kTagRememberedList[] = "rememberedList";
124 const char kTagShowDetails[] = "showDetails";
125 const char kTagShowViewAccountButton[] = "showViewAccountButton";
126 const char kTagSimOpChangePin[] = "changePin";
127 const char kTagSimOpConfigure[] = "configure";
128 const char kTagSimOpSetLocked[] = "setLocked";
129 const char kTagSimOpSetUnlocked[] = "setUnlocked";
130 const char kTagSimOpUnlock[] = "unlock";
131 const char kTagTrue[] = "true";
132 const char kTagVpnList[] = "vpnList";
133 const char kTagWifiAvailable[] = "wifiAvailable";
134 const char kTagWifiEnabled[] = "wifiEnabled";
135 const char kTagWimaxAvailable[] = "wimaxAvailable";
136 const char kTagWimaxEnabled[] = "wimaxEnabled";
137 const char kTagWiredList[] = "wiredList";
138 const char kTagWirelessList[] = "wirelessList";
139
140 // Pseudo-ONC chrome specific properties appended to the ONC dictionary.
141 const char kTagErrorMessage[] = "errorMessage";
142 const char kNetworkInfoKeyServicePath[] = "servicePath";
143 const char kNetworkInfoKeyGUID[] = "GUID";
144
145 const int kPreferredPriority = 1;
146
147 void ShillError(const std::string& function,
148                 const std::string& error_name,
149                 scoped_ptr<base::DictionaryValue> error_data) {
150   // UpdateConnectionData may send requests for stale services; ignore
151   // these errors.
152   if (function == "UpdateConnectionData" &&
153       error_name == network_handler::kDBusFailedError)
154     return;
155   NET_LOG_ERROR("Shill Error from InternetOptionsHandler: " + error_name,
156                 function);
157 }
158
159 const NetworkState* GetNetworkState(const std::string& service_path) {
160   return NetworkHandler::Get()->network_state_handler()->
161       GetNetworkState(service_path);
162 }
163
164 void SetNetworkProperty(const std::string& service_path,
165                         const std::string& property,
166                         base::Value* value) {
167   NET_LOG_EVENT("SetNetworkProperty: " + property, service_path);
168   base::DictionaryValue properties;
169   properties.SetWithoutPathExpansion(property, value);
170   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
171       service_path, properties,
172       base::Bind(&base::DoNothing),
173       base::Bind(&ShillError, "SetNetworkProperty"));
174 }
175
176 // Builds a dictionary with network information and an icon used for the
177 // NetworkList on the settings page. Ownership of the returned pointer is
178 // transferred to the caller.
179 base::DictionaryValue* BuildNetworkDictionary(
180     const NetworkState* network,
181     float icon_scale_factor,
182     const PrefService* profile_prefs) {
183   scoped_ptr<base::DictionaryValue> network_info =
184       network_util::TranslateNetworkStateToONC(network);
185
186   bool has_policy = onc::HasPolicyForNetwork(
187       profile_prefs, g_browser_process->local_state(), *network);
188   network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, has_policy);
189
190   std::string icon_url = ui::network_icon::GetImageUrlForNetwork(
191       network, ui::network_icon::ICON_TYPE_LIST, icon_scale_factor);
192
193   network_info->SetString(kNetworkInfoKeyIconURL, icon_url);
194   network_info->SetString(kNetworkInfoKeyServicePath, network->path());
195
196   return network_info.release();
197 }
198
199 bool ShowViewAccountButton(const NetworkState* cellular) {
200   if (cellular->activation_state() != shill::kActivationStateActivating &&
201       cellular->activation_state() != shill::kActivationStateActivated)
202     return false;
203
204   const DeviceState* device =
205       NetworkHandler::Get()->network_state_handler()->GetDeviceState(
206           cellular->device_path());
207
208   // If no online payment URL was provided by shill, Check to see if the
209   // MobileConfig carrier indicates that "View Account" should be shown.
210   if (cellular->payment_url().empty()) {
211     if (!device || !MobileConfig::GetInstance()->IsReady())
212       return false;
213     const MobileConfig::Carrier* carrier =
214         MobileConfig::GetInstance()->GetCarrier(device->home_provider_id());
215     if (!carrier || !carrier->show_portal_button())
216       return false;
217   }
218
219   if (!cellular->IsConnectedState()) {
220     // Disconnected LTE networks should show the button if we are online and
221     // the device's MDN is set. This is to enable users to update their plan
222     // if they are out of credits.
223     if (!NetworkHandler::Get()->network_state_handler()->DefaultNetwork())
224       return false;
225     const std::string& technology = cellular->network_technology();
226     if (technology != shill::kNetworkTechnologyLte &&
227         technology != shill::kNetworkTechnologyLteAdvanced)
228       return false;
229     std::string mdn;
230     if (device) {
231       device->properties().GetStringWithoutPathExpansion(shill::kMdnProperty,
232                                                          &mdn);
233     }
234     if (mdn.empty())
235       return false;
236   }
237
238   return true;
239 }
240
241 scoped_ptr<base::DictionaryValue> PopulateConnectionDetails(
242     const NetworkState* network,
243     const base::DictionaryValue& onc_properties) {
244   scoped_ptr<base::DictionaryValue> dictionary(onc_properties.DeepCopy());
245
246   // Append Service Path for now.
247   dictionary->SetString(kNetworkInfoKeyServicePath, network->path());
248   // Append a Chrome specific translated error message.
249   dictionary->SetString(
250       kTagErrorMessage,
251       ash::network_connect::ErrorString(network->error(), network->path()));
252
253   return dictionary.Pass();
254 }
255
256 // Helper methods for SetIPConfigProperties
257 bool AppendPropertyKeyIfPresent(const std::string& key,
258                                 const base::DictionaryValue& old_properties,
259                                 std::vector<std::string>* property_keys) {
260   if (old_properties.HasKey(key)) {
261     property_keys->push_back(key);
262     return true;
263   }
264   return false;
265 }
266
267 bool AddStringPropertyIfChanged(const std::string& key,
268                                 const std::string& new_value,
269                                 const base::DictionaryValue& old_properties,
270                                 base::DictionaryValue* new_properties) {
271   std::string old_value;
272   if (!old_properties.GetStringWithoutPathExpansion(key, &old_value) ||
273       new_value != old_value) {
274     new_properties->SetStringWithoutPathExpansion(key, new_value);
275     return true;
276   }
277   return false;
278 }
279
280 bool AddIntegerPropertyIfChanged(const std::string& key,
281                                  int new_value,
282                                  const base::DictionaryValue& old_properties,
283                                  base::DictionaryValue* new_properties) {
284   int old_value;
285   if (!old_properties.GetIntegerWithoutPathExpansion(key, &old_value) ||
286       new_value != old_value) {
287     new_properties->SetIntegerWithoutPathExpansion(key, new_value);
288     return true;
289   }
290   return false;
291 }
292
293 void RequestReconnect(const std::string& service_path) {
294   NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
295       service_path,
296       base::Bind(&ash::network_connect::ConnectToNetwork, service_path),
297       base::Bind(&ShillError, "RequestReconnect"));
298 }
299
300 }  // namespace
301
302 InternetOptionsHandler::InternetOptionsHandler()
303     : weak_factory_(this) {
304   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
305 }
306
307 InternetOptionsHandler::~InternetOptionsHandler() {
308   if (NetworkHandler::IsInitialized()) {
309     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
310         this, FROM_HERE);
311   }
312 }
313
314 void InternetOptionsHandler::GetLocalizedValues(
315     base::DictionaryValue* localized_strings) {
316   DCHECK(localized_strings);
317   internet_options_strings::RegisterLocalizedStrings(localized_strings);
318
319   // TODO(stevenjb): Find a better way to populate initial data before
320   // InitializePage() gets called.
321   std::string owner;
322   chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
323   localized_strings->SetString("ownerUserId", base::UTF8ToUTF16(owner));
324   bool logged_in_as_owner = LoginState::Get()->GetLoggedInUserType() ==
325                             LoginState::LOGGED_IN_USER_OWNER;
326   localized_strings->SetBoolean("loggedInAsOwner", logged_in_as_owner);
327
328   base::DictionaryValue* network_dictionary = new base::DictionaryValue;
329   FillNetworkInfo(network_dictionary);
330   localized_strings->Set("networkData", network_dictionary);
331 }
332
333 void InternetOptionsHandler::InitializePage() {
334   base::DictionaryValue dictionary;
335   dictionary.SetString(::onc::network_type::kCellular,
336       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK));
337   dictionary.SetString(::onc::network_type::kWiFi,
338       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK));
339   dictionary.SetString(::onc::network_type::kVPN,
340       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_VPN));
341   web_ui()->CallJavascriptFunction(kSetDefaultNetworkIconsFunction,
342                                    dictionary);
343   NetworkHandler::Get()->network_state_handler()->RequestScan();
344   RefreshNetworkData();
345 }
346
347 void InternetOptionsHandler::RegisterMessages() {
348   // Setup handlers specific to this panel.
349   web_ui()->RegisterMessageCallback(kNetworkCommandMessage,
350       base::Bind(&InternetOptionsHandler::NetworkCommandCallback,
351                  base::Unretained(this)));
352   web_ui()->RegisterMessageCallback(kSetPreferNetworkMessage,
353       base::Bind(&InternetOptionsHandler::SetPreferNetworkCallback,
354                  base::Unretained(this)));
355   web_ui()->RegisterMessageCallback(kSetAutoConnectMessage,
356       base::Bind(&InternetOptionsHandler::SetAutoConnectCallback,
357                  base::Unretained(this)));
358   web_ui()->RegisterMessageCallback(kSetIPConfigMessage,
359       base::Bind(&InternetOptionsHandler::SetIPConfigCallback,
360                  base::Unretained(this)));
361   web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage,
362       base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback,
363                  base::Unretained(this)));
364   web_ui()->RegisterMessageCallback(kSetApnMessage,
365       base::Bind(&InternetOptionsHandler::SetApnCallback,
366                  base::Unretained(this)));
367   web_ui()->RegisterMessageCallback(kSetCarrierMessage,
368       base::Bind(&InternetOptionsHandler::SetCarrierCallback,
369                  base::Unretained(this)));
370   web_ui()->RegisterMessageCallback(kSimOperationMessage,
371       base::Bind(&InternetOptionsHandler::SimOperationCallback,
372                  base::Unretained(this)));
373   web_ui()->RegisterMessageCallback(kSetServerHostname,
374       base::Bind(&InternetOptionsHandler::SetServerHostnameCallback,
375                  base::Unretained(this)));
376
377   // networkingPrivate methods
378   web_ui()->RegisterMessageCallback(kDisableNetworkTypeMessage,
379       base::Bind(&InternetOptionsHandler::DisableNetworkTypeCallback,
380                  base::Unretained(this)));
381   web_ui()->RegisterMessageCallback(kEnableNetworkTypeMessage,
382       base::Bind(&InternetOptionsHandler::EnableNetworkTypeCallback,
383                  base::Unretained(this)));
384   web_ui()->RegisterMessageCallback(kGetManagedPropertiesMessage,
385       base::Bind(&InternetOptionsHandler::GetManagedPropertiesCallback,
386                  base::Unretained(this)));
387   web_ui()->RegisterMessageCallback(kRequestNetworkScanMessage,
388       base::Bind(&InternetOptionsHandler::RequestNetworkScanCallback,
389                  base::Unretained(this)));
390   web_ui()->RegisterMessageCallback(kStartConnectMessage,
391       base::Bind(&InternetOptionsHandler::StartConnectCallback,
392                  base::Unretained(this)));
393   web_ui()->RegisterMessageCallback(kStartDisconnectMessage,
394       base::Bind(&InternetOptionsHandler::StartDisconnectCallback,
395                  base::Unretained(this)));
396 }
397
398 void InternetOptionsHandler::ShowMorePlanInfoCallback(
399     const base::ListValue* args) {
400   if (!web_ui())
401     return;
402   std::string service_path;
403   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
404     NOTREACHED();
405     return;
406   }
407   ash::network_connect::ShowMobileSetup(service_path);
408 }
409
410 void InternetOptionsHandler::SetApnCallback(const base::ListValue* args) {
411   std::string service_path;
412   if (!args->GetString(0, &service_path)) {
413     NOTREACHED();
414     return;
415   }
416   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
417       service_path,
418       base::Bind(&InternetOptionsHandler::SetApnProperties,
419                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
420       base::Bind(&ShillError, "SetApnCallback"));
421 }
422
423 void InternetOptionsHandler::SetApnProperties(
424     const base::ListValue* args,
425     const std::string& service_path,
426     const base::DictionaryValue& shill_properties) {
427   std::string apn, username, password;
428   if (!args->GetString(1, &apn) ||
429       !args->GetString(2, &username) ||
430       !args->GetString(3, &password)) {
431     NOTREACHED();
432     return;
433   }
434   NET_LOG_EVENT("SetApnCallback", service_path);
435
436   if (apn.empty()) {
437     std::vector<std::string> properties_to_clear;
438     properties_to_clear.push_back(shill::kCellularApnProperty);
439     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
440       service_path, properties_to_clear,
441       base::Bind(&base::DoNothing),
442       base::Bind(&ShillError, "ClearCellularApnProperties"));
443     return;
444   }
445
446   const base::DictionaryValue* shill_apn_dict = NULL;
447   std::string network_id;
448   if (shill_properties.GetDictionaryWithoutPathExpansion(
449           shill::kCellularApnProperty, &shill_apn_dict)) {
450     shill_apn_dict->GetStringWithoutPathExpansion(
451         shill::kApnNetworkIdProperty, &network_id);
452   }
453   base::DictionaryValue properties;
454   base::DictionaryValue* apn_dict = new base::DictionaryValue;
455   apn_dict->SetStringWithoutPathExpansion(shill::kApnProperty, apn);
456   apn_dict->SetStringWithoutPathExpansion(shill::kApnNetworkIdProperty,
457                                           network_id);
458   apn_dict->SetStringWithoutPathExpansion(shill::kApnUsernameProperty,
459                                           username);
460   apn_dict->SetStringWithoutPathExpansion(shill::kApnPasswordProperty,
461                                           password);
462   properties.SetWithoutPathExpansion(shill::kCellularApnProperty, apn_dict);
463   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
464       service_path, properties,
465       base::Bind(&base::DoNothing),
466       base::Bind(&ShillError, "SetApnProperties"));
467 }
468
469 void InternetOptionsHandler::CarrierStatusCallback() {
470   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
471   const DeviceState* device =
472       handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
473   if (device && (device->carrier() == shill::kCarrierSprint)) {
474     const NetworkState* network =
475         handler->FirstNetworkByType(NetworkTypePattern::Cellular());
476     if (network && network->path() == details_path_) {
477       ash::network_connect::ActivateCellular(network->path());
478       UpdateConnectionData(network->path());
479     }
480   }
481   UpdateCarrier();
482 }
483
484 void InternetOptionsHandler::SetCarrierCallback(const base::ListValue* args) {
485   std::string service_path;
486   std::string carrier;
487   if (args->GetSize() != 2 ||
488       !args->GetString(0, &service_path) ||
489       !args->GetString(1, &carrier)) {
490     NOTREACHED();
491     return;
492   }
493   const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
494       GetDeviceStateByType(NetworkTypePattern::Cellular());
495   if (!device) {
496     LOG(WARNING) << "SetCarrierCallback with no cellular device.";
497     return;
498   }
499   NetworkHandler::Get()->network_device_handler()->SetCarrier(
500       device->path(),
501       carrier,
502       base::Bind(&InternetOptionsHandler::CarrierStatusCallback,
503                  weak_factory_.GetWeakPtr()),
504       base::Bind(&ShillError, "SetCarrierCallback"));
505 }
506
507 void InternetOptionsHandler::SimOperationCallback(const base::ListValue* args) {
508   std::string operation;
509   if (args->GetSize() != 1 || !args->GetString(0, &operation)) {
510     NOTREACHED();
511     return;
512   }
513   if (operation == kTagSimOpConfigure) {
514     mobile_config_ui::DisplayConfigDialog();
515     return;
516   }
517   // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL.
518   // 2. Dialog will ask for current PIN in any case.
519   // 3. If card is locked it will first call PIN unlock operation
520   // 4. Then it will call Set RequirePin, passing the same PIN.
521   // 5. The dialog may change device properties, in which case
522   //    DevicePropertiesUpdated() will get called which will update the UI.
523   SimDialogDelegate::SimDialogMode mode;
524   if (operation == kTagSimOpSetLocked) {
525     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON;
526   } else if (operation == kTagSimOpSetUnlocked) {
527     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF;
528   } else if (operation == kTagSimOpUnlock) {
529     mode = SimDialogDelegate::SIM_DIALOG_UNLOCK;
530   } else if (operation == kTagSimOpChangePin) {
531     mode = SimDialogDelegate::SIM_DIALOG_CHANGE_PIN;
532   } else {
533     NOTREACHED();
534     return;
535   }
536   SimDialogDelegate::ShowDialog(GetNativeWindow(), mode);
537 }
538
539 ////////////////////////////////////////////////////////////////////////////////
540 // networkingPrivate implementation methods. TODO(stevenjb): Use the
541 // networkingPrivate API directly in the settings JS and deprecate these
542 // methods. crbug.com/279351.
543
544 void InternetOptionsHandler::DisableNetworkTypeCallback(
545     const base::ListValue* args) {
546   std::string type;
547   if (!args->GetString(0, &type)) {
548     NOTREACHED();
549     return;
550   }
551   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
552       chromeos::onc::NetworkTypePatternFromOncType(type), false,
553       base::Bind(&ShillError, "DisableNetworkType"));
554 }
555
556 void InternetOptionsHandler::EnableNetworkTypeCallback(
557     const base::ListValue* args) {
558   std::string type;
559   if (!args->GetString(0, &type)) {
560     NOTREACHED();
561     return;
562   }
563   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
564       chromeos::onc::NetworkTypePatternFromOncType(type), true,
565       base::Bind(&ShillError, "EnableNetworkType"));
566 }
567
568 void InternetOptionsHandler::GetManagedPropertiesCallback(
569     const base::ListValue* args) {
570   std::string service_path;
571   if (!args->GetString(0, &service_path)) {
572     NOTREACHED();
573     return;
574   }
575   NetworkHandler::Get()->managed_network_configuration_handler()
576       ->GetManagedProperties(
577           LoginState::Get()->primary_user_hash(),
578           service_path,
579           base::Bind(
580               &InternetOptionsHandler::PopulateDictionaryDetailsCallback,
581               weak_factory_.GetWeakPtr()),
582           base::Bind(&ShillError, "GetManagedProperties"));
583 }
584
585 void InternetOptionsHandler::RequestNetworkScanCallback(
586     const base::ListValue* args) {
587   NetworkHandler::Get()->network_state_handler()->RequestScan();
588 }
589
590 void InternetOptionsHandler::StartConnectCallback(const base::ListValue* args) {
591   std::string service_path;
592   if (!args->GetString(0, &service_path)) {
593     NOTREACHED();
594     return;
595   }
596   ash::network_connect::ConnectToNetwork(service_path);
597 }
598
599 void InternetOptionsHandler::StartDisconnectCallback(
600     const base::ListValue* args) {
601   std::string service_path;
602   if (!args->GetString(0, &service_path)) {
603     NOTREACHED();
604     return;
605   }
606   NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
607       service_path,
608       base::Bind(&base::DoNothing),
609       base::Bind(&ShillError, "StartDisconnectCallback"));
610 }
611
612 ////////////////////////////////////////////////////////////////////////////////
613
614 std::string InternetOptionsHandler::GetIconDataUrl(int resource_id) const {
615   gfx::ImageSkia* icon =
616       ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
617   gfx::ImageSkiaRep image_rep = icon->GetRepresentation(
618       web_ui()->GetDeviceScaleFactor());
619   return webui::GetBitmapDataUrl(image_rep.sk_bitmap());
620 }
621
622 void InternetOptionsHandler::RefreshNetworkData() {
623   base::DictionaryValue dictionary;
624   FillNetworkInfo(&dictionary);
625   web_ui()->CallJavascriptFunction(kRefreshNetworkDataFunction, dictionary);
626 }
627
628 void InternetOptionsHandler::UpdateConnectionData(
629     const std::string& service_path) {
630   NetworkHandler::Get()
631       ->managed_network_configuration_handler()
632       ->GetManagedProperties(
633           LoginState::Get()->primary_user_hash(),
634           service_path,
635           base::Bind(&InternetOptionsHandler::UpdateConnectionDataCallback,
636                      weak_factory_.GetWeakPtr()),
637           base::Bind(&ShillError, "UpdateConnectionData"));
638 }
639
640 void InternetOptionsHandler::UpdateConnectionDataCallback(
641     const std::string& service_path,
642     const base::DictionaryValue& onc_properties) {
643   const NetworkState* network = GetNetworkState(service_path);
644   if (!network)
645     return;
646   scoped_ptr<base::DictionaryValue> dictionary =
647       PopulateConnectionDetails(network, onc_properties);
648   web_ui()->CallJavascriptFunction(kUpdateConnectionDataFunction, *dictionary);
649 }
650
651 void InternetOptionsHandler::UpdateCarrier() {
652   web_ui()->CallJavascriptFunction(kUpdateCarrierFunction);
653 }
654
655 void InternetOptionsHandler::DeviceListChanged() {
656   if (!web_ui())
657     return;
658   RefreshNetworkData();
659 }
660
661 void InternetOptionsHandler::NetworkListChanged() {
662   if (!web_ui())
663     return;
664   RefreshNetworkData();
665 }
666
667 void InternetOptionsHandler::NetworkConnectionStateChanged(
668     const NetworkState* network) {
669   if (!web_ui())
670     return;
671   if (network->path() == details_path_)
672     UpdateConnectionData(network->path());
673 }
674
675 void InternetOptionsHandler::NetworkPropertiesUpdated(
676     const NetworkState* network) {
677   if (!web_ui())
678     return;
679   RefreshNetworkData();
680   if (network->path() == details_path_)
681     UpdateConnectionData(network->path());
682 }
683
684 void InternetOptionsHandler::DevicePropertiesUpdated(
685     const DeviceState* device) {
686   if (!web_ui())
687     return;
688   if (device->type() != shill::kTypeCellular)
689     return;
690   const NetworkState* network =
691       NetworkHandler::Get()->network_state_handler()->FirstNetworkByType(
692           NetworkTypePattern::Cellular());
693   if (network && network->path() == details_path_)
694     UpdateConnectionData(network->path());
695 }
696
697 void InternetOptionsHandler::SetServerHostnameCallback(
698     const base::ListValue* args) {
699   std::string service_path, server_hostname;
700   if (args->GetSize() < 2 ||
701       !args->GetString(0, &service_path) ||
702       !args->GetString(1, &server_hostname)) {
703     NOTREACHED();
704     return;
705   }
706   SetNetworkProperty(service_path,
707                      shill::kProviderHostProperty,
708                      new base::StringValue(server_hostname));
709 }
710
711 void InternetOptionsHandler::SetPreferNetworkCallback(
712     const base::ListValue* args) {
713   std::string service_path, prefer_network_str;
714   if (args->GetSize() < 2 ||
715       !args->GetString(0, &service_path) ||
716       !args->GetString(1, &prefer_network_str)) {
717     NOTREACHED();
718     return;
719   }
720   int priority = (prefer_network_str == kTagTrue) ? kPreferredPriority : 0;
721   SetNetworkProperty(service_path,
722                      shill::kPriorityProperty,
723                      new base::FundamentalValue(priority));
724 }
725
726 void InternetOptionsHandler::SetAutoConnectCallback(
727     const base::ListValue* args) {
728   std::string service_path, auto_connect_str;
729   if (args->GetSize() < 2 ||
730       !args->GetString(0, &service_path) ||
731       !args->GetString(1, &auto_connect_str)) {
732     NOTREACHED();
733     return;
734   }
735   bool auto_connect = auto_connect_str == kTagTrue;
736   SetNetworkProperty(service_path,
737                      shill::kAutoConnectProperty,
738                      new base::FundamentalValue(auto_connect));
739 }
740
741 void InternetOptionsHandler::SetIPConfigCallback(const base::ListValue* args) {
742   std::string service_path;
743   if (!args->GetString(0, &service_path)) {
744     NOTREACHED();
745     return;
746   }
747   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
748       service_path,
749       base::Bind(&InternetOptionsHandler::SetIPConfigProperties,
750                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
751       base::Bind(&ShillError, "SetIPConfigCallback"));
752 }
753
754 void InternetOptionsHandler::SetIPConfigProperties(
755     const base::ListValue* args,
756     const std::string& service_path,
757     const base::DictionaryValue& shill_properties) {
758   std::string address, netmask, gateway, name_server_type, name_servers;
759   bool dhcp_for_ip;
760   if (!args->GetBoolean(1, &dhcp_for_ip) ||
761       !args->GetString(2, &address) ||
762       !args->GetString(3, &netmask) ||
763       !args->GetString(4, &gateway) ||
764       !args->GetString(5, &name_server_type) ||
765       !args->GetString(6, &name_servers)) {
766     NOTREACHED();
767     return;
768   }
769   NET_LOG_USER("SetIPConfigProperties", service_path);
770
771   bool request_reconnect = false;
772   std::vector<std::string> properties_to_clear;
773   base::DictionaryValue properties_to_set;
774
775   if (dhcp_for_ip) {
776     request_reconnect |= AppendPropertyKeyIfPresent(
777         shill::kStaticIPAddressProperty,
778         shill_properties, &properties_to_clear);
779     request_reconnect |= AppendPropertyKeyIfPresent(
780         shill::kStaticIPPrefixlenProperty,
781         shill_properties, &properties_to_clear);
782     request_reconnect |= AppendPropertyKeyIfPresent(
783         shill::kStaticIPGatewayProperty,
784         shill_properties, &properties_to_clear);
785   } else {
786     request_reconnect |= AddStringPropertyIfChanged(
787         shill::kStaticIPAddressProperty,
788         address, shill_properties, &properties_to_set);
789     int prefixlen = network_util::NetmaskToPrefixLength(netmask);
790     if (prefixlen < 0) {
791       LOG(ERROR) << "Invalid prefix length for: " << service_path
792                  << " with netmask " << netmask;
793       prefixlen = 0;
794     }
795     request_reconnect |= AddIntegerPropertyIfChanged(
796         shill::kStaticIPPrefixlenProperty,
797         prefixlen, shill_properties, &properties_to_set);
798     request_reconnect |= AddStringPropertyIfChanged(
799         shill::kStaticIPGatewayProperty,
800         gateway, shill_properties, &properties_to_set);
801   }
802
803   if (name_server_type == kNameServerTypeAutomatic) {
804     AppendPropertyKeyIfPresent(shill::kStaticIPNameServersProperty,
805                                shill_properties, &properties_to_clear);
806   } else {
807     if (name_server_type == kNameServerTypeGoogle)
808       name_servers = kGoogleNameServers;
809     AddStringPropertyIfChanged(
810         shill::kStaticIPNameServersProperty,
811         name_servers, shill_properties, &properties_to_set);
812   }
813
814   if (!properties_to_clear.empty()) {
815     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
816       service_path, properties_to_clear,
817       base::Bind(&base::DoNothing),
818       base::Bind(&ShillError, "ClearIPConfigProperties"));
819   }
820   if (!properties_to_set.empty()) {
821     NetworkHandler::Get()->network_configuration_handler()->SetProperties(
822         service_path, properties_to_set,
823         base::Bind(&base::DoNothing),
824         base::Bind(&ShillError, "SetIPConfigProperties"));
825   }
826   std::string device_path;
827   shill_properties.GetStringWithoutPathExpansion(
828       shill::kDeviceProperty, &device_path);
829   if (!device_path.empty()) {
830     base::Closure callback = base::Bind(&base::DoNothing);
831     // If auto config or a static IP property changed, we need to reconnect
832     // to the network.
833     if (request_reconnect)
834       callback = base::Bind(&RequestReconnect, service_path);
835     NetworkHandler::Get()->network_device_handler()->RequestRefreshIPConfigs(
836         device_path,
837         callback,
838         base::Bind(&ShillError, "RequestRefreshIPConfigs"));
839   }
840 }
841
842 void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
843     const std::string& service_path,
844     const base::DictionaryValue& onc_properties) {
845   const NetworkState* network = GetNetworkState(service_path);
846   if (!network) {
847     LOG(ERROR) << "Network properties not found: " << service_path;
848     return;
849   }
850   scoped_ptr<base::DictionaryValue> dictionary =
851       PopulateConnectionDetails(network, onc_properties);
852
853   // Show details dialog
854   web_ui()->CallJavascriptFunction(kSendNetworkDetailsFunction, *dictionary);
855 }
856
857 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
858   return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
859 }
860
861 float InternetOptionsHandler::GetScaleFactor() const {
862   return web_ui()->GetDeviceScaleFactor();
863 }
864
865 const PrefService* InternetOptionsHandler::GetPrefs() const {
866   return Profile::FromWebUI(web_ui())->GetPrefs();
867 }
868
869 void InternetOptionsHandler::NetworkCommandCallback(
870     const base::ListValue* args) {
871   std::string onc_type;
872   std::string service_path;
873   std::string command;
874   if (args->GetSize() != 3 ||
875       !args->GetString(0, &onc_type) ||
876       !args->GetString(1, &service_path) ||
877       !args->GetString(2, &command)) {
878     NOTREACHED();
879     return;
880   }
881   std::string type;  // Shill type
882   if (!onc_type.empty()) {
883     type = network_util::TranslateONCTypeToShill(onc_type);
884     if (type.empty())
885       LOG(ERROR) << "Unable to translate ONC type: " << onc_type;
886   }
887   // Process commands that do not require an existing network.
888   if (command == kTagAddConnection) {
889     AddConnection(type);
890   } else if (command == kTagForget) {
891     NetworkHandler::Get()->network_configuration_handler()->
892         RemoveConfiguration(
893             service_path,
894             base::Bind(&base::DoNothing),
895             base::Bind(&ShillError, "NetworkCommand: " + command));
896   } else if (command == kTagShowDetails) {
897     SendShowDetailedInfo(service_path);
898   } else if (command == kTagConfigure) {
899     NetworkConfigView::Show(service_path, GetNativeWindow());
900   } else if (command == kTagActivate && type == shill::kTypeCellular) {
901     ash::network_connect::ActivateCellular(service_path);
902     // Activation may update network properties (e.g. ActivationState), so
903     // request them here in case they change.
904     UpdateConnectionData(service_path);
905   } else {
906     LOG(ERROR) << "Unknown internet options command: " << command;
907     NOTREACHED();
908   }
909 }
910
911 void InternetOptionsHandler::AddConnection(const std::string& type) {
912   if (type == shill::kTypeWifi) {
913     NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow());
914   } else if (type == shill::kTypeVPN) {
915     NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow());
916   } else if (type == shill::kTypeCellular) {
917     ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
918   } else {
919     LOG(ERROR) << "Unsupported type for AddConnection";
920   }
921 }
922
923 void InternetOptionsHandler::SendShowDetailedInfo(
924     const std::string& service_path) {
925   details_path_ = service_path;
926
927   scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue);
928   const NetworkState* network = GetNetworkState(service_path);
929   if (network) {
930     dictionary->SetString(kNetworkInfoKeyServicePath, service_path);
931     dictionary->SetString(kNetworkInfoKeyGUID, network->guid());
932     if (network->type() == shill::kTypeCellular) {
933       dictionary->SetBoolean(
934           kTagCarrierSelectFlag,
935           CommandLine::ForCurrentProcess()
936           ->HasSwitch(chromeos::switches::kEnableCarrierSwitching));
937       dictionary->SetBoolean(kTagShowViewAccountButton,
938                              ShowViewAccountButton(network));
939     }
940   }
941   web_ui()->CallJavascriptFunction(kShowDetailedInfoFunction, *dictionary);
942 }
943
944 base::ListValue* InternetOptionsHandler::GetWiredList() {
945   base::ListValue* list = new base::ListValue();
946   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
947       FirstNetworkByType(NetworkTypePattern::Ethernet());
948   if (!network)
949     return list;
950   list->Append(BuildNetworkDictionary(network, GetScaleFactor(), GetPrefs()));
951   return list;
952 }
953
954 base::ListValue* InternetOptionsHandler::GetWirelessList() {
955   base::ListValue* list = new base::ListValue();
956
957   NetworkStateHandler::NetworkStateList networks;
958   NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
959       NetworkTypePattern::Wireless(), &networks);
960   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
961            networks.begin(); iter != networks.end(); ++iter) {
962     list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs()));
963   }
964
965   return list;
966 }
967
968 base::ListValue* InternetOptionsHandler::GetVPNList() {
969   base::ListValue* list = new base::ListValue();
970
971   NetworkStateHandler::NetworkStateList networks;
972   NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
973       NetworkTypePattern::VPN(), &networks);
974   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
975            networks.begin(); iter != networks.end(); ++iter) {
976     list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs()));
977   }
978
979   return list;
980 }
981
982 base::ListValue* InternetOptionsHandler::GetRememberedList() {
983   base::ListValue* list = new base::ListValue();
984
985   NetworkStateHandler::NetworkStateList networks;
986   NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
987       NetworkTypePattern::Default(),
988       true /* configured_only */,
989       false /* visible_only */,
990       0 /* no limit */,
991       &networks);
992   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
993            networks.begin(); iter != networks.end(); ++iter) {
994     const NetworkState* network = *iter;
995     if (network->type() != shill::kTypeWifi &&
996         network->type() != shill::kTypeVPN)
997       continue;
998     list->Append(
999         BuildNetworkDictionary(network,
1000                                web_ui()->GetDeviceScaleFactor(),
1001                                Profile::FromWebUI(web_ui())->GetPrefs()));
1002   }
1003
1004   return list;
1005 }
1006
1007 void InternetOptionsHandler::FillNetworkInfo(
1008     base::DictionaryValue* dictionary) {
1009   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
1010   dictionary->Set(kTagWiredList, GetWiredList());
1011   dictionary->Set(kTagWirelessList, GetWirelessList());
1012   dictionary->Set(kTagVpnList, GetVPNList());
1013   dictionary->Set(kTagRememberedList, GetRememberedList());
1014
1015   dictionary->SetBoolean(
1016       kTagWifiAvailable,
1017       handler->IsTechnologyAvailable(NetworkTypePattern::WiFi()));
1018   dictionary->SetBoolean(
1019       kTagWifiEnabled,
1020       handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()));
1021
1022   const DeviceState* cellular =
1023       handler->GetDeviceStateByType(NetworkTypePattern::Mobile());
1024   dictionary->SetBoolean(
1025       kTagCellularAvailable,
1026       handler->IsTechnologyAvailable(NetworkTypePattern::Mobile()));
1027   dictionary->SetBoolean(
1028       kTagCellularEnabled,
1029       handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()));
1030   dictionary->SetBoolean(kTagCellularSupportsScan,
1031                          cellular && cellular->support_network_scan());
1032   dictionary->SetBoolean(kTagCellularSimAbsent,
1033                          cellular && cellular->IsSimAbsent());
1034   dictionary->SetString(kTagCellularSimLockType,
1035                         cellular ? cellular->sim_lock_type() : "");
1036
1037   dictionary->SetBoolean(
1038       kTagWimaxAvailable,
1039       handler->IsTechnologyAvailable(NetworkTypePattern::Wimax()));
1040   dictionary->SetBoolean(
1041       kTagWimaxEnabled,
1042       handler->IsTechnologyEnabled(NetworkTypePattern::Wimax()));
1043 }
1044
1045 }  // namespace options
1046 }  // namespace chromeos