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/mobile_config.h"
19 #include "chrome/browser/chromeos/options/network_config_view.h"
20 #include "chrome/browser/chromeos/profiles/profile_helper.h"
21 #include "chrome/browser/chromeos/settings/cros_settings.h"
22 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
23 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
24 #include "chrome/browser/chromeos/ui/mobile_config_ui.h"
25 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h"
28 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h"
29 #include "chromeos/login/login_state.h"
30 #include "chromeos/network/network_state.h"
31 #include "chromeos/network/network_state_handler.h"
32 #include "components/onc/onc_constants.h"
33 #include "components/user_manager/user_manager.h"
34 #include "content/public/browser/web_contents.h"
35 #include "content/public/browser/web_ui.h"
36 #include "extensions/browser/api/vpn_provider/vpn_service.h"
37 #include "extensions/browser/api/vpn_provider/vpn_service_factory.h"
38 #include "extensions/browser/extension_registry.h"
39 #include "extensions/common/extension.h"
40 #include "extensions/common/extension_set.h"
41 #include "extensions/common/permissions/api_permission.h"
42 #include "extensions/common/permissions/permissions_data.h"
43 #include "third_party/cros_system_api/dbus/service_constants.h"
44 #include "ui/base/l10n/l10n_util.h"
45 #include "ui/base/webui/web_ui_util.h"
46 #include "ui/chromeos/network/network_connect.h"
47 #include "ui/chromeos/strings/grit/ui_chromeos_strings.h"
54 // Keys for the initial "localized" dictionary values.
55 const char kLoggedInAsOwnerKey
[] = "loggedInAsOwner";
56 const char kShowCarrierSelectKey
[] = "showCarrierSelect";
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
);
142 // TODO(anujsharma): Remove kShowCarrierSelectKey, as it is not
144 localized_strings
->SetBoolean(kShowCarrierSelectKey
, false);
147 void InternetOptionsHandler::InitializePage() {
148 UpdateVPNProviders();
151 void InternetOptionsHandler::RegisterMessages() {
152 web_ui()->RegisterMessageCallback(kAddVPNConnectionMessage
,
153 base::Bind(&InternetOptionsHandler::AddVPNConnection
,
154 base::Unretained(this)));
155 web_ui()->RegisterMessageCallback(kAddNonVPNConnectionMessage
,
156 base::Bind(&InternetOptionsHandler::AddNonVPNConnection
,
157 base::Unretained(this)));
158 web_ui()->RegisterMessageCallback(kConfigureNetworkMessage
,
159 base::Bind(&InternetOptionsHandler::ConfigureNetwork
,
160 base::Unretained(this)));
161 web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage
,
162 base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback
,
163 base::Unretained(this)));
164 web_ui()->RegisterMessageCallback(kSimOperationMessage
,
165 base::Bind(&InternetOptionsHandler::SimOperationCallback
,
166 base::Unretained(this)));
167 web_ui()->RegisterMessageCallback(
169 base::Bind(&InternetOptionsHandler::LoadVPNProvidersCallback
,
170 base::Unretained(this)));
173 void InternetOptionsHandler::OnExtensionLoaded(
174 content::BrowserContext
* browser_context
,
175 const extensions::Extension
* extension
) {
176 if (IsVPNProvider(extension
))
177 UpdateVPNProviders();
180 void InternetOptionsHandler::OnExtensionUnloaded(
181 content::BrowserContext
* browser_context
,
182 const extensions::Extension
* extension
,
183 extensions::UnloadedExtensionInfo::Reason reason
) {
184 if (IsVPNProvider(extension
))
185 UpdateVPNProviders();
188 void InternetOptionsHandler::OnShutdown(
189 extensions::ExtensionRegistry
* registry
) {
190 registry
->RemoveObserver(this);
193 void InternetOptionsHandler::ShowMorePlanInfoCallback(
194 const base::ListValue
* args
) {
198 if (args
->GetSize() != 1 || !args
->GetString(0, &guid
)) {
202 std::string service_path
= ServicePathFromGuid(guid
);
203 if (!service_path
.empty())
204 ui::NetworkConnect::Get()->ShowMobileSetup(service_path
);
207 void InternetOptionsHandler::SimOperationCallback(const base::ListValue
* args
) {
208 std::string operation
;
209 if (args
->GetSize() != 1 || !args
->GetString(0, &operation
)) {
213 if (operation
== kTagSimOpConfigure
) {
214 mobile_config_ui::DisplayConfigDialog();
217 // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL.
218 // 2. Dialog will ask for current PIN in any case.
219 // 3. If card is locked it will first call PIN unlock operation
220 // 4. Then it will call Set RequirePin, passing the same PIN.
221 // 5. The dialog may change device properties, in which case
222 // DevicePropertiesUpdated() will get called which will update the UI.
223 SimDialogDelegate::SimDialogMode mode
;
224 if (operation
== kTagSimOpSetLocked
) {
225 mode
= SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON
;
226 } else if (operation
== kTagSimOpSetUnlocked
) {
227 mode
= SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF
;
228 } else if (operation
== kTagSimOpUnlock
) {
229 mode
= SimDialogDelegate::SIM_DIALOG_UNLOCK
;
230 } else if (operation
== kTagSimOpChangePin
) {
231 mode
= SimDialogDelegate::SIM_DIALOG_CHANGE_PIN
;
236 SimDialogDelegate::ShowDialog(GetNativeWindow(), mode
);
239 ////////////////////////////////////////////////////////////////////////////////
241 void InternetOptionsHandler::UpdateVPNProviders() {
242 extensions::ExtensionRegistry
* const registry
=
243 GetExtensionRegistryForPrimaryUser();
245 base::ListValue vpn_providers
;
246 const extensions::ExtensionSet
& extensions
= registry
->enabled_extensions();
247 for (const auto& extension
: extensions
) {
248 if (IsVPNProvider(extension
.get())) {
249 vpn_providers
.Append(BuildVPNProviderDictionary(
250 extension
->name(), extension
->id()).release());
253 // Add the built-in OpenVPN/L2TP provider.
254 vpn_providers
.Append(
255 BuildVPNProviderDictionary(
256 l10n_util::GetStringUTF8(IDS_NETWORK_VPN_BUILT_IN_PROVIDER
),
257 std::string() /* third_party_provider_extension_id */).release());
258 web_ui()->CallJavascriptFunction(kSetVPNProvidersFunction
, vpn_providers
);
261 gfx::NativeWindow
InternetOptionsHandler::GetNativeWindow() const {
262 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
265 const PrefService
* InternetOptionsHandler::GetPrefs() const {
266 return Profile::FromWebUI(web_ui())->GetPrefs();
270 void InternetOptionsHandler::AddVPNConnection(const base::ListValue
* args
) {
272 // Show the "add network" dialog for the built-in OpenVPN/L2TP provider.
273 NetworkConfigView::ShowForType(shill::kTypeVPN
, GetNativeWindow());
277 std::string extension_id
;
278 if (args
->GetSize() != 1 || !args
->GetString(0, &extension_id
)) {
283 // Request that the third-party VPN provider identified by |provider_id|
284 // show its "add network" dialog.
285 chromeos::VpnServiceFactory::GetForBrowserContext(
286 GetProfileForPrimaryUser())->SendShowAddDialogToExtension(extension_id
);
289 void InternetOptionsHandler::AddNonVPNConnection(const base::ListValue
* args
) {
290 std::string onc_type
;
291 if (args
->GetSize() != 1 || !args
->GetString(0, &onc_type
)) {
295 if (onc_type
== ::onc::network_type::kWiFi
) {
296 NetworkConfigView::ShowForType(shill::kTypeWifi
, GetNativeWindow());
297 } else if (onc_type
== ::onc::network_type::kCellular
) {
298 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
300 LOG(ERROR
) << "Unsupported type for AddConnection";
304 void InternetOptionsHandler::ConfigureNetwork(const base::ListValue
* args
) {
306 if (args
->GetSize() != 1 || !args
->GetString(0, &guid
)) {
310 const std::string service_path
= ServicePathFromGuid(guid
);
311 if (service_path
.empty())
314 const NetworkState
* network
= GetNetworkState(service_path
);
318 if (network
->type() == shill::kTypeVPN
&&
319 network
->vpn_provider_type() == shill::kProviderThirdPartyVpn
) {
320 // Request that the third-party VPN provider used by the |network| show a
321 // configuration dialog for it.
322 VpnServiceFactory::GetForBrowserContext(GetProfileForPrimaryUser())
323 ->SendShowConfigureDialogToExtension(
324 network
->third_party_vpn_provider_extension_id(), network
->name());
328 NetworkConfigView::Show(service_path
, GetNativeWindow());
331 void InternetOptionsHandler::LoadVPNProvidersCallback(
332 const base::ListValue
* args
) {
333 UpdateVPNProviders();
336 } // namespace options
337 } // namespace chromeos