1 // Copyright 2013 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/extensions/chromeos/kiosk_apps_handler.h"
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/sys_info.h"
16 #include "base/values.h"
17 #include "chrome/browser/chromeos/login/user_manager.h"
18 #include "chrome/browser/chromeos/settings/cros_settings.h"
19 #include "chrome/common/extensions/extension_constants.h"
20 #include "chromeos/chromeos_switches.h"
21 #include "chromeos/settings/cros_settings_names.h"
22 #include "content/public/browser/web_ui.h"
23 #include "content/public/browser/web_ui_data_source.h"
24 #include "extensions/common/extension.h"
25 #include "grit/chromium_strings.h"
26 #include "grit/generated_resources.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/webui/web_ui_util.h"
35 // Populates app info dictionary with |app_data|.
36 void PopulateAppDict(const KioskAppManager::App
& app_data
,
37 base::DictionaryValue
* app_dict
) {
38 std::string
icon_url("chrome://theme/IDR_APP_DEFAULT_ICON");
40 // TODO(xiyuan): Replace data url with a URLDataSource.
41 if (!app_data
.icon
.isNull())
42 icon_url
= webui::GetBitmapDataUrl(*app_data
.icon
.bitmap());
44 app_dict
->SetString("id", app_data
.app_id
);
45 app_dict
->SetString("name", app_data
.name
);
46 app_dict
->SetString("iconURL", icon_url
);
49 KioskAppManager::Get()->GetAutoLaunchApp() == app_data
.app_id
&&
50 (KioskAppManager::Get()->IsAutoLaunchEnabled() ||
51 KioskAppManager::Get()->IsAutoLaunchRequested()));
52 app_dict
->SetBoolean("isLoading", app_data
.is_loading
);
55 // Sanitize app id input value and extracts app id out of it.
56 // Returns false if an app id could not be derived out of the input.
57 bool ExtractsAppIdFromInput(const std::string
& input
,
58 std::string
* app_id
) {
59 if (extensions::Extension::IdIsValid(input
)) {
64 GURL webstore_url
= GURL(input
);
65 if (!webstore_url
.is_valid())
68 GURL webstore_base_url
=
69 GURL(extension_urls::GetWebstoreItemDetailURLPrefix());
71 if (webstore_url
.scheme() != webstore_base_url
.scheme() ||
72 webstore_url
.host() != webstore_base_url
.host() ||
74 webstore_url
.path(), webstore_base_url
.path(), true)) {
78 const std::string path
= webstore_url
.path();
79 const size_t last_slash
= path
.rfind('/');
80 if (last_slash
== std::string::npos
)
83 const std::string candidate_id
= path
.substr(last_slash
+ 1);
84 if (!extensions::Extension::IdIsValid(candidate_id
))
87 *app_id
= candidate_id
;
93 KioskAppsHandler::KioskAppsHandler()
94 : kiosk_app_manager_(KioskAppManager::Get()),
96 is_kiosk_enabled_(false),
97 weak_ptr_factory_(this) {
98 kiosk_app_manager_
->AddObserver(this);
101 KioskAppsHandler::~KioskAppsHandler() {
102 kiosk_app_manager_
->RemoveObserver(this);
105 void KioskAppsHandler::RegisterMessages() {
106 web_ui()->RegisterMessageCallback("initializeKioskAppSettings",
107 base::Bind(&KioskAppsHandler::HandleInitializeKioskAppSettings
,
108 base::Unretained(this)));
109 web_ui()->RegisterMessageCallback("getKioskAppSettings",
110 base::Bind(&KioskAppsHandler::HandleGetKioskAppSettings
,
111 base::Unretained(this)));
112 web_ui()->RegisterMessageCallback("addKioskApp",
113 base::Bind(&KioskAppsHandler::HandleAddKioskApp
,
114 base::Unretained(this)));
115 web_ui()->RegisterMessageCallback("removeKioskApp",
116 base::Bind(&KioskAppsHandler::HandleRemoveKioskApp
,
117 base::Unretained(this)));
118 web_ui()->RegisterMessageCallback("enableKioskAutoLaunch",
119 base::Bind(&KioskAppsHandler::HandleEnableKioskAutoLaunch
,
120 base::Unretained(this)));
121 web_ui()->RegisterMessageCallback("disableKioskAutoLaunch",
122 base::Bind(&KioskAppsHandler::HandleDisableKioskAutoLaunch
,
123 base::Unretained(this)));
124 web_ui()->RegisterMessageCallback("setDisableBailoutShortcut",
125 base::Bind(&KioskAppsHandler::HandleSetDisableBailoutShortcut
,
126 base::Unretained(this)));
129 void KioskAppsHandler::GetLocalizedValues(content::WebUIDataSource
* source
) {
132 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ADD_KIOSK_APP_BUTTON
));
135 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_OVERLAY_TITLE
));
138 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP
));
140 "kioskAppIdEditHint",
141 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP_HINT
));
143 "enableAutoLaunchButton",
144 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ENABLE_AUTO_LAUNCH
));
146 "disableAutoLaunchButton",
147 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_DISABLE_AUTO_LAUNCH
));
150 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_AUTO_LAUNCH
));
153 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_INVALID_APP
));
155 "kioskDiableBailoutShortcutLabel",
156 l10n_util::GetStringUTF16(
157 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_LABEL
));
159 "kioskDisableBailoutShortcutWarningBold",
160 l10n_util::GetStringUTF16(
161 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_BOLD
));
162 const base::string16 product_os_name
=
163 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME
);
165 "kioskDisableBailoutShortcutWarning",
166 l10n_util::GetStringFUTF16(
167 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_FORMAT
,
170 "kioskDisableBailoutShortcutConfirm",
171 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL
));
173 "kioskDisableBailoutShortcutCancel",
174 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL
));
175 source
->AddString("done", l10n_util::GetStringUTF16(IDS_DONE
));
176 source
->AddString("add", l10n_util::GetStringUTF16(IDS_ADD
));
179 void KioskAppsHandler::OnKioskAppDataChanged(const std::string
& app_id
) {
180 KioskAppManager::App app_data
;
181 if (!kiosk_app_manager_
->GetApp(app_id
, &app_data
))
184 base::DictionaryValue app_dict
;
185 PopulateAppDict(app_data
, &app_dict
);
187 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.updateApp",
191 void KioskAppsHandler::OnKioskAppDataLoadFailure(const std::string
& app_id
) {
192 base::StringValue
app_id_value(app_id
);
193 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.showError",
198 void KioskAppsHandler::OnGetConsumerKioskModeStatus(
199 chromeos::KioskAppManager::ConsumerKioskModeStatus status
) {
202 ((status
== KioskAppManager::CONSUMER_KIOSK_MODE_ENABLED
) &&
203 chromeos::UserManager::Get()->IsCurrentUserOwner()) ||
204 !base::SysInfo::IsRunningOnChromeOS();
206 if (is_kiosk_enabled_
) {
207 base::FundamentalValue
enabled(is_kiosk_enabled_
);
208 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.enableKiosk",
214 void KioskAppsHandler::OnKioskAppsSettingsChanged() {
215 SendKioskAppSettings();
218 void KioskAppsHandler::SendKioskAppSettings() {
219 if (!initialized_
|| !is_kiosk_enabled_
)
222 bool enable_bailout_shortcut
;
223 if (!CrosSettings::Get()->GetBoolean(
224 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled
,
225 &enable_bailout_shortcut
)) {
226 enable_bailout_shortcut
= true;
229 base::DictionaryValue settings
;
230 settings
.SetBoolean("disableBailout", !enable_bailout_shortcut
);
232 KioskAppManager::Apps apps
;
233 kiosk_app_manager_
->GetApps(&apps
);
235 scoped_ptr
<base::ListValue
> apps_list(new base::ListValue
);
236 for (size_t i
= 0; i
< apps
.size(); ++i
) {
237 const KioskAppManager::App
& app_data
= apps
[i
];
239 scoped_ptr
<base::DictionaryValue
> app_info(new base::DictionaryValue
);
240 PopulateAppDict(app_data
, app_info
.get());
241 apps_list
->Append(app_info
.release());
243 settings
.SetWithoutPathExpansion("apps", apps_list
.release());
245 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.setSettings",
249 void KioskAppsHandler::HandleInitializeKioskAppSettings(
250 const base::ListValue
* args
) {
251 KioskAppManager::Get()->GetConsumerKioskModeStatus(
252 base::Bind(&KioskAppsHandler::OnGetConsumerKioskModeStatus
,
253 weak_ptr_factory_
.GetWeakPtr()));
256 void KioskAppsHandler::HandleGetKioskAppSettings(const base::ListValue
* args
) {
257 SendKioskAppSettings();
261 void KioskAppsHandler::HandleAddKioskApp(const base::ListValue
* args
) {
262 if (!initialized_
|| !is_kiosk_enabled_
)
266 CHECK(args
->GetString(0, &input
));
269 if (!ExtractsAppIdFromInput(input
, &app_id
)) {
270 OnKioskAppDataLoadFailure(input
);
274 kiosk_app_manager_
->AddApp(app_id
);
277 void KioskAppsHandler::HandleRemoveKioskApp(const base::ListValue
* args
) {
278 if (!initialized_
|| !is_kiosk_enabled_
)
282 CHECK(args
->GetString(0, &app_id
));
284 kiosk_app_manager_
->RemoveApp(app_id
);
287 void KioskAppsHandler::HandleEnableKioskAutoLaunch(
288 const base::ListValue
* args
) {
289 if (!initialized_
|| !is_kiosk_enabled_
)
293 CHECK(args
->GetString(0, &app_id
));
295 kiosk_app_manager_
->SetAutoLaunchApp(app_id
);
298 void KioskAppsHandler::HandleDisableKioskAutoLaunch(
299 const base::ListValue
* args
) {
300 if (!initialized_
|| !is_kiosk_enabled_
)
304 CHECK(args
->GetString(0, &app_id
));
306 std::string startup_app_id
= kiosk_app_manager_
->GetAutoLaunchApp();
307 if (startup_app_id
!= app_id
)
310 kiosk_app_manager_
->SetAutoLaunchApp("");
313 void KioskAppsHandler::HandleSetDisableBailoutShortcut(
314 const base::ListValue
* args
) {
315 if (!initialized_
|| !is_kiosk_enabled_
)
318 bool disable_bailout_shortcut
;
319 CHECK(args
->GetBoolean(0, &disable_bailout_shortcut
));
321 CrosSettings::Get()->SetBoolean(
322 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled
,
323 !disable_bailout_shortcut
);
326 } // namespace chromeos