Upstream version 11.39.250.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 }  // namespace
294
295 InternetOptionsHandler::InternetOptionsHandler()
296     : weak_factory_(this) {
297   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
298 }
299
300 InternetOptionsHandler::~InternetOptionsHandler() {
301   if (NetworkHandler::IsInitialized()) {
302     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
303         this, FROM_HERE);
304   }
305 }
306
307 void InternetOptionsHandler::GetLocalizedValues(
308     base::DictionaryValue* localized_strings) {
309   DCHECK(localized_strings);
310   internet_options_strings::RegisterLocalizedStrings(localized_strings);
311
312   // TODO(stevenjb): Find a better way to populate initial data before
313   // InitializePage() gets called.
314   std::string owner;
315   chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
316   localized_strings->SetString("ownerUserId", base::UTF8ToUTF16(owner));
317   bool logged_in_as_owner = LoginState::Get()->GetLoggedInUserType() ==
318                             LoginState::LOGGED_IN_USER_OWNER;
319   localized_strings->SetBoolean("loggedInAsOwner", logged_in_as_owner);
320
321   base::DictionaryValue* network_dictionary = new base::DictionaryValue;
322   FillNetworkInfo(network_dictionary);
323   localized_strings->Set("networkData", network_dictionary);
324 }
325
326 void InternetOptionsHandler::InitializePage() {
327   base::DictionaryValue dictionary;
328   dictionary.SetString(::onc::network_type::kCellular,
329       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK));
330   dictionary.SetString(::onc::network_type::kWiFi,
331       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK));
332   dictionary.SetString(::onc::network_type::kVPN,
333       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_VPN));
334   web_ui()->CallJavascriptFunction(kSetDefaultNetworkIconsFunction,
335                                    dictionary);
336   NetworkHandler::Get()->network_state_handler()->RequestScan();
337   RefreshNetworkData();
338 }
339
340 void InternetOptionsHandler::RegisterMessages() {
341   // Setup handlers specific to this panel.
342   web_ui()->RegisterMessageCallback(kNetworkCommandMessage,
343       base::Bind(&InternetOptionsHandler::NetworkCommandCallback,
344                  base::Unretained(this)));
345   web_ui()->RegisterMessageCallback(kSetPreferNetworkMessage,
346       base::Bind(&InternetOptionsHandler::SetPreferNetworkCallback,
347                  base::Unretained(this)));
348   web_ui()->RegisterMessageCallback(kSetAutoConnectMessage,
349       base::Bind(&InternetOptionsHandler::SetAutoConnectCallback,
350                  base::Unretained(this)));
351   web_ui()->RegisterMessageCallback(kSetIPConfigMessage,
352       base::Bind(&InternetOptionsHandler::SetIPConfigCallback,
353                  base::Unretained(this)));
354   web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage,
355       base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback,
356                  base::Unretained(this)));
357   web_ui()->RegisterMessageCallback(kSetApnMessage,
358       base::Bind(&InternetOptionsHandler::SetApnCallback,
359                  base::Unretained(this)));
360   web_ui()->RegisterMessageCallback(kSetCarrierMessage,
361       base::Bind(&InternetOptionsHandler::SetCarrierCallback,
362                  base::Unretained(this)));
363   web_ui()->RegisterMessageCallback(kSimOperationMessage,
364       base::Bind(&InternetOptionsHandler::SimOperationCallback,
365                  base::Unretained(this)));
366   web_ui()->RegisterMessageCallback(kSetServerHostname,
367       base::Bind(&InternetOptionsHandler::SetServerHostnameCallback,
368                  base::Unretained(this)));
369
370   // networkingPrivate methods
371   web_ui()->RegisterMessageCallback(kDisableNetworkTypeMessage,
372       base::Bind(&InternetOptionsHandler::DisableNetworkTypeCallback,
373                  base::Unretained(this)));
374   web_ui()->RegisterMessageCallback(kEnableNetworkTypeMessage,
375       base::Bind(&InternetOptionsHandler::EnableNetworkTypeCallback,
376                  base::Unretained(this)));
377   web_ui()->RegisterMessageCallback(kGetManagedPropertiesMessage,
378       base::Bind(&InternetOptionsHandler::GetManagedPropertiesCallback,
379                  base::Unretained(this)));
380   web_ui()->RegisterMessageCallback(kRequestNetworkScanMessage,
381       base::Bind(&InternetOptionsHandler::RequestNetworkScanCallback,
382                  base::Unretained(this)));
383   web_ui()->RegisterMessageCallback(kStartConnectMessage,
384       base::Bind(&InternetOptionsHandler::StartConnectCallback,
385                  base::Unretained(this)));
386   web_ui()->RegisterMessageCallback(kStartDisconnectMessage,
387       base::Bind(&InternetOptionsHandler::StartDisconnectCallback,
388                  base::Unretained(this)));
389 }
390
391 void InternetOptionsHandler::ShowMorePlanInfoCallback(
392     const base::ListValue* args) {
393   if (!web_ui())
394     return;
395   std::string service_path;
396   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
397     NOTREACHED();
398     return;
399   }
400   ash::network_connect::ShowMobileSetup(service_path);
401 }
402
403 void InternetOptionsHandler::SetApnCallback(const base::ListValue* args) {
404   std::string service_path;
405   if (!args->GetString(0, &service_path)) {
406     NOTREACHED();
407     return;
408   }
409   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
410       service_path,
411       base::Bind(&InternetOptionsHandler::SetApnProperties,
412                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
413       base::Bind(&ShillError, "SetApnCallback"));
414 }
415
416 void InternetOptionsHandler::SetApnProperties(
417     const base::ListValue* args,
418     const std::string& service_path,
419     const base::DictionaryValue& shill_properties) {
420   std::string apn, username, password;
421   if (!args->GetString(1, &apn) ||
422       !args->GetString(2, &username) ||
423       !args->GetString(3, &password)) {
424     NOTREACHED();
425     return;
426   }
427   NET_LOG_EVENT("SetApnCallback", service_path);
428
429   if (apn.empty()) {
430     std::vector<std::string> properties_to_clear;
431     properties_to_clear.push_back(shill::kCellularApnProperty);
432     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
433       service_path, properties_to_clear,
434       base::Bind(&base::DoNothing),
435       base::Bind(&ShillError, "ClearCellularApnProperties"));
436     return;
437   }
438
439   const base::DictionaryValue* shill_apn_dict = NULL;
440   std::string network_id;
441   if (shill_properties.GetDictionaryWithoutPathExpansion(
442           shill::kCellularApnProperty, &shill_apn_dict)) {
443     shill_apn_dict->GetStringWithoutPathExpansion(
444         shill::kApnNetworkIdProperty, &network_id);
445   }
446   base::DictionaryValue properties;
447   base::DictionaryValue* apn_dict = new base::DictionaryValue;
448   apn_dict->SetStringWithoutPathExpansion(shill::kApnProperty, apn);
449   apn_dict->SetStringWithoutPathExpansion(shill::kApnNetworkIdProperty,
450                                           network_id);
451   apn_dict->SetStringWithoutPathExpansion(shill::kApnUsernameProperty,
452                                           username);
453   apn_dict->SetStringWithoutPathExpansion(shill::kApnPasswordProperty,
454                                           password);
455   properties.SetWithoutPathExpansion(shill::kCellularApnProperty, apn_dict);
456   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
457       service_path, properties,
458       base::Bind(&base::DoNothing),
459       base::Bind(&ShillError, "SetApnProperties"));
460 }
461
462 void InternetOptionsHandler::CarrierStatusCallback() {
463   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
464   const DeviceState* device =
465       handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
466   if (device && (device->carrier() == shill::kCarrierSprint)) {
467     const NetworkState* network =
468         handler->FirstNetworkByType(NetworkTypePattern::Cellular());
469     if (network && network->path() == details_path_) {
470       ash::network_connect::ActivateCellular(network->path());
471       UpdateConnectionData(network->path());
472     }
473   }
474   UpdateCarrier();
475 }
476
477 void InternetOptionsHandler::SetCarrierCallback(const base::ListValue* args) {
478   std::string service_path;
479   std::string carrier;
480   if (args->GetSize() != 2 ||
481       !args->GetString(0, &service_path) ||
482       !args->GetString(1, &carrier)) {
483     NOTREACHED();
484     return;
485   }
486   const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
487       GetDeviceStateByType(NetworkTypePattern::Cellular());
488   if (!device) {
489     LOG(WARNING) << "SetCarrierCallback with no cellular device.";
490     return;
491   }
492   NetworkHandler::Get()->network_device_handler()->SetCarrier(
493       device->path(),
494       carrier,
495       base::Bind(&InternetOptionsHandler::CarrierStatusCallback,
496                  weak_factory_.GetWeakPtr()),
497       base::Bind(&ShillError, "SetCarrierCallback"));
498 }
499
500 void InternetOptionsHandler::SimOperationCallback(const base::ListValue* args) {
501   std::string operation;
502   if (args->GetSize() != 1 || !args->GetString(0, &operation)) {
503     NOTREACHED();
504     return;
505   }
506   if (operation == kTagSimOpConfigure) {
507     mobile_config_ui::DisplayConfigDialog();
508     return;
509   }
510   // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL.
511   // 2. Dialog will ask for current PIN in any case.
512   // 3. If card is locked it will first call PIN unlock operation
513   // 4. Then it will call Set RequirePin, passing the same PIN.
514   // 5. The dialog may change device properties, in which case
515   //    DevicePropertiesUpdated() will get called which will update the UI.
516   SimDialogDelegate::SimDialogMode mode;
517   if (operation == kTagSimOpSetLocked) {
518     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON;
519   } else if (operation == kTagSimOpSetUnlocked) {
520     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF;
521   } else if (operation == kTagSimOpUnlock) {
522     mode = SimDialogDelegate::SIM_DIALOG_UNLOCK;
523   } else if (operation == kTagSimOpChangePin) {
524     mode = SimDialogDelegate::SIM_DIALOG_CHANGE_PIN;
525   } else {
526     NOTREACHED();
527     return;
528   }
529   SimDialogDelegate::ShowDialog(GetNativeWindow(), mode);
530 }
531
532 ////////////////////////////////////////////////////////////////////////////////
533 // networkingPrivate implementation methods. TODO(stevenjb): Use the
534 // networkingPrivate API directly in the settings JS and deprecate these
535 // methods. crbug.com/279351.
536
537 void InternetOptionsHandler::DisableNetworkTypeCallback(
538     const base::ListValue* args) {
539   std::string type;
540   if (!args->GetString(0, &type)) {
541     NOTREACHED();
542     return;
543   }
544   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
545       chromeos::onc::NetworkTypePatternFromOncType(type), false,
546       base::Bind(&ShillError, "DisableNetworkType"));
547 }
548
549 void InternetOptionsHandler::EnableNetworkTypeCallback(
550     const base::ListValue* args) {
551   std::string type;
552   if (!args->GetString(0, &type)) {
553     NOTREACHED();
554     return;
555   }
556   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
557       chromeos::onc::NetworkTypePatternFromOncType(type), true,
558       base::Bind(&ShillError, "EnableNetworkType"));
559 }
560
561 void InternetOptionsHandler::GetManagedPropertiesCallback(
562     const base::ListValue* args) {
563   std::string service_path;
564   if (!args->GetString(0, &service_path)) {
565     NOTREACHED();
566     return;
567   }
568   NetworkHandler::Get()->managed_network_configuration_handler()
569       ->GetManagedProperties(
570           LoginState::Get()->primary_user_hash(),
571           service_path,
572           base::Bind(
573               &InternetOptionsHandler::PopulateDictionaryDetailsCallback,
574               weak_factory_.GetWeakPtr()),
575           base::Bind(&ShillError, "GetManagedProperties"));
576 }
577
578 void InternetOptionsHandler::RequestNetworkScanCallback(
579     const base::ListValue* args) {
580   NetworkHandler::Get()->network_state_handler()->RequestScan();
581 }
582
583 void InternetOptionsHandler::StartConnectCallback(const base::ListValue* args) {
584   std::string service_path;
585   if (!args->GetString(0, &service_path)) {
586     NOTREACHED();
587     return;
588   }
589   ash::network_connect::ConnectToNetwork(service_path);
590 }
591
592 void InternetOptionsHandler::StartDisconnectCallback(
593     const base::ListValue* args) {
594   std::string service_path;
595   if (!args->GetString(0, &service_path)) {
596     NOTREACHED();
597     return;
598   }
599   NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
600       service_path,
601       base::Bind(&base::DoNothing),
602       base::Bind(&ShillError, "StartDisconnectCallback"));
603 }
604
605 ////////////////////////////////////////////////////////////////////////////////
606
607 std::string InternetOptionsHandler::GetIconDataUrl(int resource_id) const {
608   gfx::ImageSkia* icon =
609       ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
610   gfx::ImageSkiaRep image_rep = icon->GetRepresentation(
611       web_ui()->GetDeviceScaleFactor());
612   return webui::GetBitmapDataUrl(image_rep.sk_bitmap());
613 }
614
615 void InternetOptionsHandler::RefreshNetworkData() {
616   base::DictionaryValue dictionary;
617   FillNetworkInfo(&dictionary);
618   web_ui()->CallJavascriptFunction(kRefreshNetworkDataFunction, dictionary);
619 }
620
621 void InternetOptionsHandler::UpdateConnectionData(
622     const std::string& service_path) {
623   NetworkHandler::Get()
624       ->managed_network_configuration_handler()
625       ->GetManagedProperties(
626           LoginState::Get()->primary_user_hash(),
627           service_path,
628           base::Bind(&InternetOptionsHandler::UpdateConnectionDataCallback,
629                      weak_factory_.GetWeakPtr()),
630           base::Bind(&ShillError, "UpdateConnectionData"));
631 }
632
633 void InternetOptionsHandler::UpdateConnectionDataCallback(
634     const std::string& service_path,
635     const base::DictionaryValue& onc_properties) {
636   const NetworkState* network = GetNetworkState(service_path);
637   if (!network)
638     return;
639   scoped_ptr<base::DictionaryValue> dictionary =
640       PopulateConnectionDetails(network, onc_properties);
641   web_ui()->CallJavascriptFunction(kUpdateConnectionDataFunction, *dictionary);
642 }
643
644 void InternetOptionsHandler::UpdateCarrier() {
645   web_ui()->CallJavascriptFunction(kUpdateCarrierFunction);
646 }
647
648 void InternetOptionsHandler::DeviceListChanged() {
649   if (!web_ui())
650     return;
651   RefreshNetworkData();
652 }
653
654 void InternetOptionsHandler::NetworkListChanged() {
655   if (!web_ui())
656     return;
657   RefreshNetworkData();
658 }
659
660 void InternetOptionsHandler::NetworkConnectionStateChanged(
661     const NetworkState* network) {
662   if (!web_ui())
663     return;
664   if (network->path() == details_path_)
665     UpdateConnectionData(network->path());
666 }
667
668 void InternetOptionsHandler::NetworkPropertiesUpdated(
669     const NetworkState* network) {
670   if (!web_ui())
671     return;
672   RefreshNetworkData();
673   if (network->path() == details_path_)
674     UpdateConnectionData(network->path());
675 }
676
677 void InternetOptionsHandler::DevicePropertiesUpdated(
678     const DeviceState* device) {
679   if (!web_ui())
680     return;
681   if (device->type() != shill::kTypeCellular)
682     return;
683   const NetworkState* network =
684       NetworkHandler::Get()->network_state_handler()->FirstNetworkByType(
685           NetworkTypePattern::Cellular());
686   if (network && network->path() == details_path_)
687     UpdateConnectionData(network->path());
688 }
689
690 void InternetOptionsHandler::SetServerHostnameCallback(
691     const base::ListValue* args) {
692   std::string service_path, server_hostname;
693   if (args->GetSize() < 2 ||
694       !args->GetString(0, &service_path) ||
695       !args->GetString(1, &server_hostname)) {
696     NOTREACHED();
697     return;
698   }
699   SetNetworkProperty(service_path,
700                      shill::kProviderHostProperty,
701                      new base::StringValue(server_hostname));
702 }
703
704 void InternetOptionsHandler::SetPreferNetworkCallback(
705     const base::ListValue* args) {
706   std::string service_path, prefer_network_str;
707   if (args->GetSize() < 2 ||
708       !args->GetString(0, &service_path) ||
709       !args->GetString(1, &prefer_network_str)) {
710     NOTREACHED();
711     return;
712   }
713   int priority = (prefer_network_str == kTagTrue) ? kPreferredPriority : 0;
714   SetNetworkProperty(service_path,
715                      shill::kPriorityProperty,
716                      new base::FundamentalValue(priority));
717 }
718
719 void InternetOptionsHandler::SetAutoConnectCallback(
720     const base::ListValue* args) {
721   std::string service_path, auto_connect_str;
722   if (args->GetSize() < 2 ||
723       !args->GetString(0, &service_path) ||
724       !args->GetString(1, &auto_connect_str)) {
725     NOTREACHED();
726     return;
727   }
728   bool auto_connect = auto_connect_str == kTagTrue;
729   SetNetworkProperty(service_path,
730                      shill::kAutoConnectProperty,
731                      new base::FundamentalValue(auto_connect));
732 }
733
734 void InternetOptionsHandler::SetIPConfigCallback(const base::ListValue* args) {
735   std::string service_path;
736   if (!args->GetString(0, &service_path)) {
737     NOTREACHED();
738     return;
739   }
740   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
741       service_path,
742       base::Bind(&InternetOptionsHandler::SetIPConfigProperties,
743                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
744       base::Bind(&ShillError, "SetIPConfigCallback"));
745 }
746
747 void InternetOptionsHandler::SetIPConfigProperties(
748     const base::ListValue* args,
749     const std::string& service_path,
750     const base::DictionaryValue& shill_properties) {
751   std::string address, netmask, gateway, name_server_type, name_servers;
752   bool dhcp_for_ip;
753   if (!args->GetBoolean(1, &dhcp_for_ip) ||
754       !args->GetString(2, &address) ||
755       !args->GetString(3, &netmask) ||
756       !args->GetString(4, &gateway) ||
757       !args->GetString(5, &name_server_type) ||
758       !args->GetString(6, &name_servers)) {
759     NOTREACHED();
760     return;
761   }
762   NET_LOG_USER("SetIPConfigProperties: " + name_server_type, service_path);
763
764   std::vector<std::string> properties_to_clear;
765   base::DictionaryValue properties_to_set;
766
767   if (dhcp_for_ip) {
768     AppendPropertyKeyIfPresent(shill::kStaticIPAddressProperty,
769                                shill_properties,
770                                &properties_to_clear);
771     AppendPropertyKeyIfPresent(shill::kStaticIPPrefixlenProperty,
772                                shill_properties,
773                                &properties_to_clear);
774     AppendPropertyKeyIfPresent(shill::kStaticIPGatewayProperty,
775                                shill_properties,
776                                &properties_to_clear);
777   } else {
778     AddStringPropertyIfChanged(shill::kStaticIPAddressProperty,
779                                address,
780                                shill_properties,
781                                &properties_to_set);
782     int prefixlen = network_util::NetmaskToPrefixLength(netmask);
783     if (prefixlen < 0) {
784       LOG(ERROR) << "Invalid prefix length for: " << service_path
785                  << " with netmask " << netmask;
786       prefixlen = 0;
787     }
788     AddIntegerPropertyIfChanged(shill::kStaticIPPrefixlenProperty,
789                                 prefixlen,
790                                 shill_properties,
791                                 &properties_to_set);
792     AddStringPropertyIfChanged(shill::kStaticIPGatewayProperty,
793                                gateway,
794                                shill_properties,
795                                &properties_to_set);
796   }
797
798   if (name_server_type == kNameServerTypeAutomatic) {
799     AppendPropertyKeyIfPresent(shill::kStaticIPNameServersProperty,
800                                shill_properties,
801                                &properties_to_clear);
802   } else {
803     if (name_server_type == kNameServerTypeGoogle)
804       name_servers = kGoogleNameServers;
805     AddStringPropertyIfChanged(shill::kStaticIPNameServersProperty,
806                                name_servers,
807                                shill_properties,
808                                &properties_to_set);
809   }
810
811   if (!properties_to_clear.empty()) {
812     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
813         service_path,
814         properties_to_clear,
815         base::Bind(&base::DoNothing),
816         base::Bind(&ShillError, "ClearIPConfigProperties"));
817   }
818   if (!properties_to_set.empty()) {
819     NetworkHandler::Get()->network_configuration_handler()->SetProperties(
820         service_path,
821         properties_to_set,
822         base::Bind(&base::DoNothing),
823         base::Bind(&ShillError, "SetIPConfigProperties"));
824   }
825   std::string device_path;
826   shill_properties.GetStringWithoutPathExpansion(shill::kDeviceProperty,
827                                                  &device_path);
828   if (!device_path.empty()) {
829     NetworkHandler::Get()->network_device_handler()->RequestRefreshIPConfigs(
830         device_path,
831         base::Bind(&base::DoNothing),
832         base::Bind(&ShillError, "RequestRefreshIPConfigs"));
833   }
834 }
835
836 void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
837     const std::string& service_path,
838     const base::DictionaryValue& onc_properties) {
839   const NetworkState* network = GetNetworkState(service_path);
840   if (!network) {
841     LOG(ERROR) << "Network properties not found: " << service_path;
842     return;
843   }
844   scoped_ptr<base::DictionaryValue> dictionary =
845       PopulateConnectionDetails(network, onc_properties);
846
847   // Show details dialog
848   web_ui()->CallJavascriptFunction(kSendNetworkDetailsFunction, *dictionary);
849 }
850
851 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
852   return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
853 }
854
855 float InternetOptionsHandler::GetScaleFactor() const {
856   return web_ui()->GetDeviceScaleFactor();
857 }
858
859 const PrefService* InternetOptionsHandler::GetPrefs() const {
860   return Profile::FromWebUI(web_ui())->GetPrefs();
861 }
862
863 void InternetOptionsHandler::NetworkCommandCallback(
864     const base::ListValue* args) {
865   std::string onc_type;
866   std::string service_path;
867   std::string command;
868   if (args->GetSize() != 3 ||
869       !args->GetString(0, &onc_type) ||
870       !args->GetString(1, &service_path) ||
871       !args->GetString(2, &command)) {
872     NOTREACHED();
873     return;
874   }
875   std::string type;  // Shill type
876   if (!onc_type.empty()) {
877     type = network_util::TranslateONCTypeToShill(onc_type);
878     if (type.empty())
879       LOG(ERROR) << "Unable to translate ONC type: " << onc_type;
880   }
881   // Process commands that do not require an existing network.
882   if (command == kTagAddConnection) {
883     AddConnection(type);
884   } else if (command == kTagForget) {
885     NetworkHandler::Get()->network_configuration_handler()->
886         RemoveConfiguration(
887             service_path,
888             base::Bind(&base::DoNothing),
889             base::Bind(&ShillError, "NetworkCommand: " + command));
890   } else if (command == kTagShowDetails) {
891     SendShowDetailedInfo(service_path);
892   } else if (command == kTagConfigure) {
893     NetworkConfigView::Show(service_path, GetNativeWindow());
894   } else if (command == kTagActivate && type == shill::kTypeCellular) {
895     ash::network_connect::ActivateCellular(service_path);
896     // Activation may update network properties (e.g. ActivationState), so
897     // request them here in case they change.
898     UpdateConnectionData(service_path);
899   } else {
900     LOG(ERROR) << "Unknown internet options command: " << command;
901     NOTREACHED();
902   }
903 }
904
905 void InternetOptionsHandler::AddConnection(const std::string& type) {
906   if (type == shill::kTypeWifi) {
907     NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow());
908   } else if (type == shill::kTypeVPN) {
909     NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow());
910   } else if (type == shill::kTypeCellular) {
911     ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
912   } else {
913     LOG(ERROR) << "Unsupported type for AddConnection";
914   }
915 }
916
917 void InternetOptionsHandler::SendShowDetailedInfo(
918     const std::string& service_path) {
919   details_path_ = service_path;
920
921   scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue);
922   const NetworkState* network = GetNetworkState(service_path);
923   if (network) {
924     dictionary->SetString(kNetworkInfoKeyServicePath, service_path);
925     dictionary->SetString(kNetworkInfoKeyGUID, network->guid());
926     if (network->type() == shill::kTypeCellular) {
927       dictionary->SetBoolean(
928           kTagCarrierSelectFlag,
929           CommandLine::ForCurrentProcess()
930           ->HasSwitch(chromeos::switches::kEnableCarrierSwitching));
931       dictionary->SetBoolean(kTagShowViewAccountButton,
932                              ShowViewAccountButton(network));
933     }
934   }
935   web_ui()->CallJavascriptFunction(kShowDetailedInfoFunction, *dictionary);
936 }
937
938 base::ListValue* InternetOptionsHandler::GetWiredList() {
939   base::ListValue* list = new base::ListValue();
940   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
941       FirstNetworkByType(NetworkTypePattern::Ethernet());
942   if (!network)
943     return list;
944   list->Append(BuildNetworkDictionary(network, GetScaleFactor(), GetPrefs()));
945   return list;
946 }
947
948 base::ListValue* InternetOptionsHandler::GetWirelessList() {
949   base::ListValue* list = new base::ListValue();
950
951   NetworkStateHandler::NetworkStateList networks;
952   NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
953       NetworkTypePattern::Wireless(), &networks);
954   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
955            networks.begin(); iter != networks.end(); ++iter) {
956     list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs()));
957   }
958
959   return list;
960 }
961
962 base::ListValue* InternetOptionsHandler::GetVPNList() {
963   base::ListValue* list = new base::ListValue();
964
965   NetworkStateHandler::NetworkStateList networks;
966   NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType(
967       NetworkTypePattern::VPN(), &networks);
968   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
969            networks.begin(); iter != networks.end(); ++iter) {
970     list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs()));
971   }
972
973   return list;
974 }
975
976 base::ListValue* InternetOptionsHandler::GetRememberedList() {
977   base::ListValue* list = new base::ListValue();
978
979   NetworkStateHandler::NetworkStateList networks;
980   NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
981       NetworkTypePattern::Default(),
982       true /* configured_only */,
983       false /* visible_only */,
984       0 /* no limit */,
985       &networks);
986   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
987            networks.begin(); iter != networks.end(); ++iter) {
988     const NetworkState* network = *iter;
989     if (network->type() != shill::kTypeWifi &&
990         network->type() != shill::kTypeVPN)
991       continue;
992     list->Append(
993         BuildNetworkDictionary(network,
994                                web_ui()->GetDeviceScaleFactor(),
995                                Profile::FromWebUI(web_ui())->GetPrefs()));
996   }
997
998   return list;
999 }
1000
1001 void InternetOptionsHandler::FillNetworkInfo(
1002     base::DictionaryValue* dictionary) {
1003   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
1004   dictionary->Set(kTagWiredList, GetWiredList());
1005   dictionary->Set(kTagWirelessList, GetWirelessList());
1006   dictionary->Set(kTagVpnList, GetVPNList());
1007   dictionary->Set(kTagRememberedList, GetRememberedList());
1008
1009   dictionary->SetBoolean(
1010       kTagWifiAvailable,
1011       handler->IsTechnologyAvailable(NetworkTypePattern::WiFi()));
1012   dictionary->SetBoolean(
1013       kTagWifiEnabled,
1014       handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()));
1015
1016   const DeviceState* cellular =
1017       handler->GetDeviceStateByType(NetworkTypePattern::Mobile());
1018   dictionary->SetBoolean(
1019       kTagCellularAvailable,
1020       handler->IsTechnologyAvailable(NetworkTypePattern::Mobile()));
1021   dictionary->SetBoolean(
1022       kTagCellularEnabled,
1023       handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()));
1024   dictionary->SetBoolean(kTagCellularSupportsScan,
1025                          cellular && cellular->support_network_scan());
1026   dictionary->SetBoolean(kTagCellularSimAbsent,
1027                          cellular && cellular->IsSimAbsent());
1028   dictionary->SetString(kTagCellularSimLockType,
1029                         cellular ? cellular->sim_lock_type() : "");
1030
1031   dictionary->SetBoolean(
1032       kTagWimaxAvailable,
1033       handler->IsTechnologyAvailable(NetworkTypePattern::Wimax()));
1034   dictionary->SetBoolean(
1035       kTagWimaxEnabled,
1036       handler->IsTechnologyEnabled(NetworkTypePattern::Wimax()));
1037 }
1038
1039 }  // namespace options
1040 }  // namespace chromeos