Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / extensions / chromeos / kiosk_apps_handler.cc
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.
4
5 #include "chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h"
6
7 #include <algorithm>
8 #include <set>
9 #include <string>
10 #include <vector>
11
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"
29 #include "url/gurl.h"
30
31 namespace chromeos {
32
33 namespace {
34
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");
39
40   // TODO(xiyuan): Replace data url with a URLDataSource.
41   if (!app_data.icon.isNull())
42     icon_url = webui::GetBitmapDataUrl(*app_data.icon.bitmap());
43
44   app_dict->SetString("id", app_data.app_id);
45   app_dict->SetString("name", app_data.name);
46   app_dict->SetString("iconURL", icon_url);
47   app_dict->SetBoolean(
48       "autoLaunch",
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);
53 }
54
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)) {
60     *app_id = input;
61     return true;
62   }
63
64   GURL webstore_url = GURL(input);
65   if (!webstore_url.is_valid())
66     return false;
67
68   GURL webstore_base_url =
69       GURL(extension_urls::GetWebstoreItemDetailURLPrefix());
70
71   if (webstore_url.scheme() != webstore_base_url.scheme() ||
72       webstore_url.host() != webstore_base_url.host() ||
73       !StartsWithASCII(
74           webstore_url.path(), webstore_base_url.path(), true)) {
75     return false;
76   }
77
78   const std::string path = webstore_url.path();
79   const size_t last_slash = path.rfind('/');
80   if (last_slash == std::string::npos)
81     return false;
82
83   const std::string candidate_id = path.substr(last_slash + 1);
84   if (!extensions::Extension::IdIsValid(candidate_id))
85     return false;
86
87   *app_id = candidate_id;
88   return true;
89 }
90
91 }  // namespace
92
93 KioskAppsHandler::KioskAppsHandler()
94     : kiosk_app_manager_(KioskAppManager::Get()),
95       initialized_(false),
96       is_kiosk_enabled_(false),
97       is_auto_launch_enabled_(false),
98       weak_ptr_factory_(this) {
99   kiosk_app_manager_->AddObserver(this);
100 }
101
102 KioskAppsHandler::~KioskAppsHandler() {
103   kiosk_app_manager_->RemoveObserver(this);
104 }
105
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)));
128 }
129
130 void KioskAppsHandler::GetLocalizedValues(content::WebUIDataSource* source) {
131   source->AddString(
132       "addKioskAppButton",
133       l10n_util::GetStringUTF16(IDS_EXTENSIONS_ADD_KIOSK_APP_BUTTON));
134   source->AddString(
135       "kioskOverlayTitle",
136       l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_OVERLAY_TITLE));
137   source->AddString(
138       "addKioskApp",
139       l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP));
140   source->AddString(
141       "kioskAppIdEditHint",
142       l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP_HINT));
143   source->AddString(
144       "enableAutoLaunchButton",
145       l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ENABLE_AUTO_LAUNCH));
146   source->AddString(
147       "disableAutoLaunchButton",
148       l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_DISABLE_AUTO_LAUNCH));
149   source->AddString(
150       "autoLaunch",
151       l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_AUTO_LAUNCH));
152   source->AddString(
153       "invalidApp",
154       l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_INVALID_APP));
155   source->AddString(
156       "kioskDiableBailoutShortcutLabel",
157       l10n_util::GetStringUTF16(
158           IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_LABEL));
159   source->AddString(
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);
165   source->AddString(
166       "kioskDisableBailoutShortcutWarning",
167       l10n_util::GetStringFUTF16(
168           IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_FORMAT,
169           product_os_name));
170   source->AddString(
171       "kioskDisableBailoutShortcutConfirm",
172       l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL));
173   source->AddString(
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));
178 }
179
180 void KioskAppsHandler::OnKioskAppDataChanged(const std::string& app_id) {
181   KioskAppManager::App app_data;
182   if (!kiosk_app_manager_->GetApp(app_id, &app_data))
183     return;
184
185   base::DictionaryValue app_dict;
186   PopulateAppDict(app_data, &app_dict);
187
188   web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.updateApp",
189                                    app_dict);
190 }
191
192 void KioskAppsHandler::OnKioskAppDataLoadFailure(const std::string& app_id) {
193   base::StringValue app_id_value(app_id);
194   web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.showError",
195                                    app_id_value);
196 }
197
198
199 void KioskAppsHandler::OnGetConsumerKioskAutoLaunchStatus(
200     chromeos::KioskAppManager::ConsumerKioskAutoLaunchStatus status) {
201   initialized_ = true;
202   is_kiosk_enabled_ =
203       chromeos::UserManager::Get()->IsCurrentUserOwner() ||
204       !base::SysInfo::IsRunningOnChromeOS();
205
206   is_auto_launch_enabled_ =
207       status == KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED ||
208       !base::SysInfo::IsRunningOnChromeOS();
209
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",
215                                      kiosk_params);
216   }
217 }
218
219
220 void KioskAppsHandler::OnKioskAppsSettingsChanged() {
221   SendKioskAppSettings();
222 }
223
224 void KioskAppsHandler::SendKioskAppSettings() {
225   if (!initialized_ || !is_kiosk_enabled_)
226     return;
227
228   bool enable_bailout_shortcut;
229   if (!CrosSettings::Get()->GetBoolean(
230           kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
231           &enable_bailout_shortcut)) {
232     enable_bailout_shortcut = true;
233   }
234
235   base::DictionaryValue settings;
236   settings.SetBoolean("disableBailout", !enable_bailout_shortcut);
237
238   KioskAppManager::Apps apps;
239   kiosk_app_manager_->GetApps(&apps);
240
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];
244
245     scoped_ptr<base::DictionaryValue> app_info(new base::DictionaryValue);
246     PopulateAppDict(app_data, app_info.get());
247     apps_list->Append(app_info.release());
248   }
249   settings.SetWithoutPathExpansion("apps", apps_list.release());
250
251   web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.setSettings",
252                                    settings);
253 }
254
255 void KioskAppsHandler::HandleInitializeKioskAppSettings(
256     const base::ListValue* args) {
257   KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
258       base::Bind(&KioskAppsHandler::OnGetConsumerKioskAutoLaunchStatus,
259                  weak_ptr_factory_.GetWeakPtr()));
260 }
261
262 void KioskAppsHandler::HandleGetKioskAppSettings(const base::ListValue* args) {
263   SendKioskAppSettings();
264 }
265
266
267 void KioskAppsHandler::HandleAddKioskApp(const base::ListValue* args) {
268   if (!initialized_ || !is_kiosk_enabled_)
269     return;
270
271   std::string input;
272   CHECK(args->GetString(0, &input));
273
274   std::string app_id;
275   if (!ExtractsAppIdFromInput(input, &app_id)) {
276     OnKioskAppDataLoadFailure(input);
277     return;
278   }
279
280   kiosk_app_manager_->AddApp(app_id);
281 }
282
283 void KioskAppsHandler::HandleRemoveKioskApp(const base::ListValue* args) {
284   if (!initialized_ || !is_kiosk_enabled_)
285     return;
286
287   std::string app_id;
288   CHECK(args->GetString(0, &app_id));
289
290   kiosk_app_manager_->RemoveApp(app_id);
291 }
292
293 void KioskAppsHandler::HandleEnableKioskAutoLaunch(
294     const base::ListValue* args) {
295   if (!initialized_ || !is_kiosk_enabled_ || !is_auto_launch_enabled_)
296     return;
297
298   std::string app_id;
299   CHECK(args->GetString(0, &app_id));
300
301   kiosk_app_manager_->SetAutoLaunchApp(app_id);
302 }
303
304 void KioskAppsHandler::HandleDisableKioskAutoLaunch(
305     const base::ListValue* args) {
306   if (!initialized_ || !is_kiosk_enabled_ || !is_auto_launch_enabled_)
307     return;
308
309   std::string app_id;
310   CHECK(args->GetString(0, &app_id));
311
312   std::string startup_app_id = kiosk_app_manager_->GetAutoLaunchApp();
313   if (startup_app_id != app_id)
314     return;
315
316   kiosk_app_manager_->SetAutoLaunchApp("");
317 }
318
319 void KioskAppsHandler::HandleSetDisableBailoutShortcut(
320     const base::ListValue* args) {
321   if (!initialized_ || !is_kiosk_enabled_)
322     return;
323
324   bool disable_bailout_shortcut;
325   CHECK(args->GetBoolean(0, &disable_bailout_shortcut));
326
327   CrosSettings::Get()->SetBoolean(
328       kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
329       !disable_bailout_shortcut);
330 }
331
332 }  // namespace chromeos