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
ShillError(const std::string & function,const std::string & error_name,scoped_ptr<base::DictionaryValue> error_data)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
GetNetworkState(const std::string & service_path)159 const NetworkState* GetNetworkState(const std::string& service_path) {
160 return NetworkHandler::Get()->network_state_handler()->
161 GetNetworkState(service_path);
162 }
163
SetNetworkProperty(const std::string & service_path,const std::string & property,base::Value * value)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.
BuildNetworkDictionary(const NetworkState * network,float icon_scale_factor,const PrefService * profile_prefs)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
ShowViewAccountButton(const NetworkState * cellular)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
PopulateConnectionDetails(const NetworkState * network,const base::DictionaryValue & onc_properties)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
AppendPropertyKeyIfPresent(const std::string & key,const base::DictionaryValue & old_properties,std::vector<std::string> * property_keys)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
AddStringPropertyIfChanged(const std::string & key,const std::string & new_value,const base::DictionaryValue & old_properties,base::DictionaryValue * new_properties)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
AddIntegerPropertyIfChanged(const std::string & key,int new_value,const base::DictionaryValue & old_properties,base::DictionaryValue * new_properties)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
InternetOptionsHandler()295 InternetOptionsHandler::InternetOptionsHandler()
296 : weak_factory_(this) {
297 NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
298 }
299
~InternetOptionsHandler()300 InternetOptionsHandler::~InternetOptionsHandler() {
301 if (NetworkHandler::IsInitialized()) {
302 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
303 this, FROM_HERE);
304 }
305 }
306
GetLocalizedValues(base::DictionaryValue * localized_strings)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
InitializePage()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
RegisterMessages()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
ShowMorePlanInfoCallback(const base::ListValue * args)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
SetApnCallback(const base::ListValue * args)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
SetApnProperties(const base::ListValue * args,const std::string & service_path,const base::DictionaryValue & shill_properties)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
CarrierStatusCallback()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
SetCarrierCallback(const base::ListValue * args)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
SimOperationCallback(const base::ListValue * args)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
DisableNetworkTypeCallback(const base::ListValue * args)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
EnableNetworkTypeCallback(const base::ListValue * args)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
GetManagedPropertiesCallback(const base::ListValue * args)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
RequestNetworkScanCallback(const base::ListValue * args)578 void InternetOptionsHandler::RequestNetworkScanCallback(
579 const base::ListValue* args) {
580 NetworkHandler::Get()->network_state_handler()->RequestScan();
581 }
582
StartConnectCallback(const base::ListValue * args)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
StartDisconnectCallback(const base::ListValue * args)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
GetIconDataUrl(int resource_id) const607 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
RefreshNetworkData()615 void InternetOptionsHandler::RefreshNetworkData() {
616 base::DictionaryValue dictionary;
617 FillNetworkInfo(&dictionary);
618 web_ui()->CallJavascriptFunction(kRefreshNetworkDataFunction, dictionary);
619 }
620
UpdateConnectionData(const std::string & service_path)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
UpdateConnectionDataCallback(const std::string & service_path,const base::DictionaryValue & onc_properties)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
UpdateCarrier()644 void InternetOptionsHandler::UpdateCarrier() {
645 web_ui()->CallJavascriptFunction(kUpdateCarrierFunction);
646 }
647
DeviceListChanged()648 void InternetOptionsHandler::DeviceListChanged() {
649 if (!web_ui())
650 return;
651 RefreshNetworkData();
652 }
653
NetworkListChanged()654 void InternetOptionsHandler::NetworkListChanged() {
655 if (!web_ui())
656 return;
657 RefreshNetworkData();
658 }
659
NetworkConnectionStateChanged(const NetworkState * network)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
NetworkPropertiesUpdated(const NetworkState * network)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
DevicePropertiesUpdated(const DeviceState * device)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
SetServerHostnameCallback(const base::ListValue * args)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
SetPreferNetworkCallback(const base::ListValue * args)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
SetAutoConnectCallback(const base::ListValue * args)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
SetIPConfigCallback(const base::ListValue * args)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
SetIPConfigProperties(const base::ListValue * args,const std::string & service_path,const base::DictionaryValue & shill_properties)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
PopulateDictionaryDetailsCallback(const std::string & service_path,const base::DictionaryValue & onc_properties)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
GetNativeWindow() const851 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
852 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
853 }
854
GetScaleFactor() const855 float InternetOptionsHandler::GetScaleFactor() const {
856 return web_ui()->GetDeviceScaleFactor();
857 }
858
GetPrefs() const859 const PrefService* InternetOptionsHandler::GetPrefs() const {
860 return Profile::FromWebUI(web_ui())->GetPrefs();
861 }
862
NetworkCommandCallback(const base::ListValue * args)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
AddConnection(const std::string & type)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
SendShowDetailedInfo(const std::string & service_path)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
GetWiredList()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
GetWirelessList()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
GetVPNList()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
GetRememberedList()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
FillNetworkInfo(base::DictionaryValue * dictionary)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
1041