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 is_auto_launch_enabled_(false),
98 weak_ptr_factory_(this) {
99 kiosk_app_manager_->AddObserver(this);
102 KioskAppsHandler::~KioskAppsHandler() {
103 kiosk_app_manager_->RemoveObserver(this);
106 void KioskAppsHandler::RegisterMessages() {
107 web_ui()->RegisterMessageCallback("initializeKioskAppSettings",
108 base::Bind(&KioskAppsHandler::HandleInitializeKioskAppSettings,
109 base::Unretained(this)));
110 web_ui()->RegisterMessageCallback("getKioskAppSettings",
111 base::Bind(&KioskAppsHandler::HandleGetKioskAppSettings,
112 base::Unretained(this)));
113 web_ui()->RegisterMessageCallback("addKioskApp",
114 base::Bind(&KioskAppsHandler::HandleAddKioskApp,
115 base::Unretained(this)));
116 web_ui()->RegisterMessageCallback("removeKioskApp",
117 base::Bind(&KioskAppsHandler::HandleRemoveKioskApp,
118 base::Unretained(this)));
119 web_ui()->RegisterMessageCallback("enableKioskAutoLaunch",
120 base::Bind(&KioskAppsHandler::HandleEnableKioskAutoLaunch,
121 base::Unretained(this)));
122 web_ui()->RegisterMessageCallback("disableKioskAutoLaunch",
123 base::Bind(&KioskAppsHandler::HandleDisableKioskAutoLaunch,
124 base::Unretained(this)));
125 web_ui()->RegisterMessageCallback("setDisableBailoutShortcut",
126 base::Bind(&KioskAppsHandler::HandleSetDisableBailoutShortcut,
127 base::Unretained(this)));
130 void KioskAppsHandler::GetLocalizedValues(content::WebUIDataSource* source) {
133 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ADD_KIOSK_APP_BUTTON));
136 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_OVERLAY_TITLE));
139 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP));
141 "kioskAppIdEditHint",
142 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP_HINT));
144 "enableAutoLaunchButton",
145 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ENABLE_AUTO_LAUNCH));
147 "disableAutoLaunchButton",
148 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_DISABLE_AUTO_LAUNCH));
151 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_AUTO_LAUNCH));
154 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_INVALID_APP));
156 "kioskDiableBailoutShortcutLabel",
157 l10n_util::GetStringUTF16(
158 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_LABEL));
160 "kioskDisableBailoutShortcutWarningBold",
161 l10n_util::GetStringUTF16(
162 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_BOLD));
163 const base::string16 product_os_name =
164 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME);
166 "kioskDisableBailoutShortcutWarning",
167 l10n_util::GetStringFUTF16(
168 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_FORMAT,
171 "kioskDisableBailoutShortcutConfirm",
172 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL));
174 "kioskDisableBailoutShortcutCancel",
175 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL));
176 source->AddString("done", l10n_util::GetStringUTF16(IDS_DONE));
177 source->AddString("add", l10n_util::GetStringUTF16(IDS_ADD));
180 void KioskAppsHandler::OnKioskAppDataChanged(const std::string& app_id) {
181 KioskAppManager::App app_data;
182 if (!kiosk_app_manager_->GetApp(app_id, &app_data))
185 base::DictionaryValue app_dict;
186 PopulateAppDict(app_data, &app_dict);
188 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.updateApp",
192 void KioskAppsHandler::OnKioskAppDataLoadFailure(const std::string& app_id) {
193 base::StringValue app_id_value(app_id);
194 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.showError",
199 void KioskAppsHandler::OnGetConsumerKioskAutoLaunchStatus(
200 chromeos::KioskAppManager::ConsumerKioskAutoLaunchStatus status) {
203 chromeos::UserManager::Get()->IsCurrentUserOwner() ||
204 !base::SysInfo::IsRunningOnChromeOS();
206 is_auto_launch_enabled_ =
207 status == KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED ||
208 !base::SysInfo::IsRunningOnChromeOS();
210 if (is_kiosk_enabled_) {
211 base::DictionaryValue kiosk_params;
212 kiosk_params.SetBoolean("kioskEnabled", is_kiosk_enabled_);
213 kiosk_params.SetBoolean("autoLaunchEnabled", is_auto_launch_enabled_);
214 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.enableKiosk",
220 void KioskAppsHandler::OnKioskAppsSettingsChanged() {
221 SendKioskAppSettings();
224 void KioskAppsHandler::SendKioskAppSettings() {
225 if (!initialized_ || !is_kiosk_enabled_)
228 bool enable_bailout_shortcut;
229 if (!CrosSettings::Get()->GetBoolean(
230 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
231 &enable_bailout_shortcut)) {
232 enable_bailout_shortcut = true;
235 base::DictionaryValue settings;
236 settings.SetBoolean("disableBailout", !enable_bailout_shortcut);
238 KioskAppManager::Apps apps;
239 kiosk_app_manager_->GetApps(&apps);
241 scoped_ptr<base::ListValue> apps_list(new base::ListValue);
242 for (size_t i = 0; i < apps.size(); ++i) {
243 const KioskAppManager::App& app_data = apps[i];
245 scoped_ptr<base::DictionaryValue> app_info(new base::DictionaryValue);
246 PopulateAppDict(app_data, app_info.get());
247 apps_list->Append(app_info.release());
249 settings.SetWithoutPathExpansion("apps", apps_list.release());
251 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.setSettings",
255 void KioskAppsHandler::HandleInitializeKioskAppSettings(
256 const base::ListValue* args) {
257 KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
258 base::Bind(&KioskAppsHandler::OnGetConsumerKioskAutoLaunchStatus,
259 weak_ptr_factory_.GetWeakPtr()));
262 void KioskAppsHandler::HandleGetKioskAppSettings(const base::ListValue* args) {
263 SendKioskAppSettings();
267 void KioskAppsHandler::HandleAddKioskApp(const base::ListValue* args) {
268 if (!initialized_ || !is_kiosk_enabled_)
272 CHECK(args->GetString(0, &input));
275 if (!ExtractsAppIdFromInput(input, &app_id)) {
276 OnKioskAppDataLoadFailure(input);
280 kiosk_app_manager_->AddApp(app_id);
283 void KioskAppsHandler::HandleRemoveKioskApp(const base::ListValue* args) {
284 if (!initialized_ || !is_kiosk_enabled_)
288 CHECK(args->GetString(0, &app_id));
290 kiosk_app_manager_->RemoveApp(app_id);
293 void KioskAppsHandler::HandleEnableKioskAutoLaunch(
294 const base::ListValue* args) {
295 if (!initialized_ || !is_kiosk_enabled_ || !is_auto_launch_enabled_)
299 CHECK(args->GetString(0, &app_id));
301 kiosk_app_manager_->SetAutoLaunchApp(app_id);
304 void KioskAppsHandler::HandleDisableKioskAutoLaunch(
305 const base::ListValue* args) {
306 if (!initialized_ || !is_kiosk_enabled_ || !is_auto_launch_enabled_)
310 CHECK(args->GetString(0, &app_id));
312 std::string startup_app_id = kiosk_app_manager_->GetAutoLaunchApp();
313 if (startup_app_id != app_id)
316 kiosk_app_manager_->SetAutoLaunchApp("");
319 void KioskAppsHandler::HandleSetDisableBailoutShortcut(
320 const base::ListValue* args) {
321 if (!initialized_ || !is_kiosk_enabled_)
324 bool disable_bailout_shortcut;
325 CHECK(args->GetBoolean(0, &disable_bailout_shortcut));
327 CrosSettings::Get()->SetBoolean(
328 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
329 !disable_bailout_shortcut);
332 } // namespace chromeos