1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
13 #include "base/basictypes.h"
14 #include "base/bind.h"
15 #include "base/bind_helpers.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/values.h"
18 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
19 #include "chrome/browser/chromeos/mobile_config.h"
20 #include "chrome/browser/chromeos/options/network_config_view.h"
21 #include "chrome/browser/chromeos/profiles/profile_helper.h"
22 #include "chrome/browser/chromeos/settings/cros_settings.h"
23 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
24 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
25 #include "chrome/browser/chromeos/ui/mobile_config_ui.h"
26 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h"
29 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h"
30 #include "chromeos/login/login_state.h"
31 #include "chromeos/network/network_state.h"
32 #include "chromeos/network/network_state_handler.h"
33 #include "components/onc/onc_constants.h"
34 #include "components/user_manager/user_manager.h"
35 #include "content/public/browser/web_contents.h"
36 #include "content/public/browser/web_ui.h"
37 #include "extensions/browser/api/vpn_provider/vpn_service.h"
38 #include "extensions/browser/api/vpn_provider/vpn_service_factory.h"
39 #include "extensions/browser/extension_registry.h"
40 #include "extensions/common/extension.h"
41 #include "extensions/common/extension_set.h"
42 #include "extensions/common/permissions/api_permission.h"
43 #include "extensions/common/permissions/permissions_data.h"
44 #include "third_party/cros_system_api/dbus/service_constants.h"
45 #include "ui/base/l10n/l10n_util.h"
46 #include "ui/base/webui/web_ui_util.h"
47 #include "ui/chromeos/network/network_connect.h"
48 #include "ui/chromeos/strings/grit/ui_chromeos_strings.h"
55 // Keys for the initial "localized" dictionary values.
56 const char kLoggedInAsOwnerKey
[] = "loggedInAsOwner";
58 // Functions we call in JavaScript.
59 const char kSetVPNProvidersFunction
[] = "options.VPNProviders.setProviders";
61 // JS methods to show additional UI.
62 const char kShowMorePlanInfoMessage
[] = "showMorePlanInfo";
63 const char kSimOperationMessage
[] = "simOperation";
65 // TODO(stevenjb): Deprecate these and integrate with settings Web UI.
66 const char kAddVPNConnectionMessage
[] = "addVPNConnection";
67 const char kAddNonVPNConnectionMessage
[] = "addNonVPNConnection";
68 const char kConfigureNetworkMessage
[] = "configureNetwork";
70 const char kLoadVPNProviders
[] = "loadVPNProviders";
72 // These are strings used to communicate with JavaScript.
73 const char kTagSimOpChangePin
[] = "changePin";
74 const char kTagSimOpConfigure
[] = "configure";
75 const char kTagSimOpSetLocked
[] = "setLocked";
76 const char kTagSimOpSetUnlocked
[] = "setUnlocked";
77 const char kTagSimOpUnlock
[] = "unlock";
78 const char kTagVPNProviderName
[] = "name";
79 const char kTagVPNProviderExtensionID
[] = "extensionID";
81 const NetworkState
* GetNetworkState(const std::string
& service_path
) {
82 return NetworkHandler::Get()->network_state_handler()->
83 GetNetworkState(service_path
);
86 std::string
ServicePathFromGuid(const std::string
& guid
) {
87 const NetworkState
* network
=
88 NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid(
90 return network
? network
->path() : "";
93 bool IsVPNProvider(const extensions::Extension
* extension
) {
94 return extension
->permissions_data()->HasAPIPermission(
95 extensions::APIPermission::kVpnProvider
);
98 Profile
* GetProfileForPrimaryUser() {
99 return chromeos::ProfileHelper::Get()->GetProfileByUser(
100 user_manager::UserManager::Get()->GetPrimaryUser());
103 extensions::ExtensionRegistry
* GetExtensionRegistryForPrimaryUser() {
104 return extensions::ExtensionRegistry::Get(GetProfileForPrimaryUser());
107 scoped_ptr
<base::DictionaryValue
> BuildVPNProviderDictionary(
108 const std::string
& name
,
109 const std::string
& third_party_provider_extension_id
) {
110 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
111 dict
->SetString(kTagVPNProviderName
, name
);
112 if (!third_party_provider_extension_id
.empty()) {
113 dict
->SetString(kTagVPNProviderExtensionID
,
114 third_party_provider_extension_id
);
121 InternetOptionsHandler::InternetOptionsHandler()
122 : weak_factory_(this) {
123 GetExtensionRegistryForPrimaryUser()->AddObserver(this);
126 InternetOptionsHandler::~InternetOptionsHandler() {
127 GetExtensionRegistryForPrimaryUser()->RemoveObserver(this);
130 void InternetOptionsHandler::GetLocalizedValues(
131 base::DictionaryValue
* localized_strings
) {
132 DCHECK(localized_strings
);
133 internet_options_strings::RegisterLocalizedStrings(localized_strings
);
135 // TODO(stevenjb): Find a better way to populate initial data before
136 // InitializePage() gets called.
138 chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner
, &owner
);
139 bool logged_in_as_owner
= LoginState::Get()->GetLoggedInUserType() ==
140 LoginState::LOGGED_IN_USER_OWNER
;
141 localized_strings
->SetBoolean(kLoggedInAsOwnerKey
, logged_in_as_owner
);
144 void InternetOptionsHandler::InitializePage() {
145 UpdateVPNProviders();
148 void InternetOptionsHandler::RegisterMessages() {
149 web_ui()->RegisterMessageCallback(kAddVPNConnectionMessage
,
150 base::Bind(&InternetOptionsHandler::AddVPNConnection
,
151 base::Unretained(this)));
152 web_ui()->RegisterMessageCallback(kAddNonVPNConnectionMessage
,
153 base::Bind(&InternetOptionsHandler::AddNonVPNConnection
,
154 base::Unretained(this)));
155 web_ui()->RegisterMessageCallback(kConfigureNetworkMessage
,
156 base::Bind(&InternetOptionsHandler::ConfigureNetwork
,
157 base::Unretained(this)));
158 web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage
,
159 base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback
,
160 base::Unretained(this)));
161 web_ui()->RegisterMessageCallback(kSimOperationMessage
,
162 base::Bind(&InternetOptionsHandler::SimOperationCallback
,
163 base::Unretained(this)));
164 web_ui()->RegisterMessageCallback(
166 base::Bind(&InternetOptionsHandler::LoadVPNProvidersCallback
,
167 base::Unretained(this)));
170 void InternetOptionsHandler::OnExtensionLoaded(
171 content::BrowserContext
* browser_context
,
172 const extensions::Extension
* extension
) {
173 if (IsVPNProvider(extension
))
174 UpdateVPNProviders();
177 void InternetOptionsHandler::OnExtensionUnloaded(
178 content::BrowserContext
* browser_context
,
179 const extensions::Extension
* extension
,
180 extensions::UnloadedExtensionInfo::Reason reason
) {
181 if (IsVPNProvider(extension
))
182 UpdateVPNProviders();
185 void InternetOptionsHandler::OnShutdown(
186 extensions::ExtensionRegistry
* registry
) {
187 registry
->RemoveObserver(this);
190 void InternetOptionsHandler::ShowMorePlanInfoCallback(
191 const base::ListValue
* args
) {
195 if (args
->GetSize() != 1 || !args
->GetString(0, &guid
)) {
199 std::string service_path
= ServicePathFromGuid(guid
);
200 if (!service_path
.empty())
201 ui::NetworkConnect::Get()->ShowMobileSetup(service_path
);
204 void InternetOptionsHandler::SimOperationCallback(const base::ListValue
* args
) {
205 std::string operation
;
206 if (args
->GetSize() != 1 || !args
->GetString(0, &operation
)) {
210 if (operation
== kTagSimOpConfigure
) {
211 mobile_config_ui::DisplayConfigDialog();
214 // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL.
215 // 2. Dialog will ask for current PIN in any case.
216 // 3. If card is locked it will first call PIN unlock operation
217 // 4. Then it will call Set RequirePin, passing the same PIN.
218 // 5. The dialog may change device properties, in which case
219 // DevicePropertiesUpdated() will get called which will update the UI.
220 SimDialogDelegate::SimDialogMode mode
;
221 if (operation
== kTagSimOpSetLocked
) {
222 mode
= SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON
;
223 } else if (operation
== kTagSimOpSetUnlocked
) {
224 mode
= SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF
;
225 } else if (operation
== kTagSimOpUnlock
) {
226 mode
= SimDialogDelegate::SIM_DIALOG_UNLOCK
;
227 } else if (operation
== kTagSimOpChangePin
) {
228 mode
= SimDialogDelegate::SIM_DIALOG_CHANGE_PIN
;
233 SimDialogDelegate::ShowDialog(GetNativeWindow(), mode
);
236 ////////////////////////////////////////////////////////////////////////////////
238 void InternetOptionsHandler::UpdateVPNProviders() {
239 extensions::ExtensionRegistry
* const registry
=
240 GetExtensionRegistryForPrimaryUser();
242 base::ListValue vpn_providers
;
243 const extensions::ExtensionSet
& extensions
= registry
->enabled_extensions();
244 for (const auto& extension
: extensions
) {
245 if (IsVPNProvider(extension
.get())) {
246 vpn_providers
.Append(BuildVPNProviderDictionary(
247 extension
->name(), extension
->id()).release());
250 // Add the built-in OpenVPN/L2TP provider.
251 vpn_providers
.Append(
252 BuildVPNProviderDictionary(
253 l10n_util::GetStringUTF8(IDS_NETWORK_VPN_BUILT_IN_PROVIDER
),
254 std::string() /* third_party_provider_extension_id */).release());
255 web_ui()->CallJavascriptFunction(kSetVPNProvidersFunction
, vpn_providers
);
258 gfx::NativeWindow
InternetOptionsHandler::GetNativeWindow() const {
259 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
262 const PrefService
* InternetOptionsHandler::GetPrefs() const {
263 return Profile::FromWebUI(web_ui())->GetPrefs();
267 void InternetOptionsHandler::AddVPNConnection(const base::ListValue
* args
) {
269 // Show the "add network" dialog for the built-in OpenVPN/L2TP provider.
270 NetworkConfigView::ShowForType(shill::kTypeVPN
, GetNativeWindow());
274 std::string extension_id
;
275 if (args
->GetSize() != 1 || !args
->GetString(0, &extension_id
)) {
280 // Request that the third-party VPN provider identified by |provider_id|
281 // show its "add network" dialog.
282 chromeos::VpnServiceFactory::GetForBrowserContext(
283 GetProfileForPrimaryUser())->SendShowAddDialogToExtension(extension_id
);
286 void InternetOptionsHandler::AddNonVPNConnection(const base::ListValue
* args
) {
287 std::string onc_type
;
288 if (args
->GetSize() != 1 || !args
->GetString(0, &onc_type
)) {
292 if (onc_type
== ::onc::network_type::kWiFi
) {
293 NetworkConfigView::ShowForType(shill::kTypeWifi
, GetNativeWindow());
294 } else if (onc_type
== ::onc::network_type::kCellular
) {
295 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
297 LOG(ERROR
) << "Unsupported type for AddConnection";
301 void InternetOptionsHandler::ConfigureNetwork(const base::ListValue
* args
) {
303 if (args
->GetSize() < 1 || !args
->GetString(0, &guid
)) {
307 bool force_show
= false;
308 if (args
->GetSize() >= 2)
309 args
->GetBoolean(1, &force_show
);
311 const std::string service_path
= ServicePathFromGuid(guid
);
312 if (service_path
.empty())
315 const NetworkState
* network
= GetNetworkState(service_path
);
319 if (network
->type() == shill::kTypeVPN
&&
320 network
->vpn_provider_type() == shill::kProviderThirdPartyVpn
) {
321 // Request that the third-party VPN provider used by the |network| show a
322 // configuration dialog for it.
323 VpnServiceFactory::GetForBrowserContext(GetProfileForPrimaryUser())
324 ->SendShowConfigureDialogToExtension(
325 network
->third_party_vpn_provider_extension_id(), network
->name());
329 // If a network is not connectable, show the enrollment dialog if available.
330 if (!force_show
&& !network
->connectable() &&
331 enrollment::CreateDialog(service_path
, GetNativeWindow())) {
335 NetworkConfigView::Show(service_path
, GetNativeWindow());
338 void InternetOptionsHandler::LoadVPNProvidersCallback(
339 const base::ListValue
* args
) {
340 UpdateVPNProviders();
343 } // namespace options
344 } // namespace chromeos