Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / ui / webui / extensions / chromeos / kiosk_apps_handler.cc
blob76a312b34bbefaca0081befc340aa1fc9725ed2a
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"
7 #include <algorithm>
8 #include <set>
9 #include <string>
10 #include <vector>
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string_util.h"
16 #include "base/sys_info.h"
17 #include "base/values.h"
18 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chrome/grit/chromium_strings.h"
21 #include "chrome/grit/generated_resources.h"
22 #include "chromeos/chromeos_switches.h"
23 #include "chromeos/settings/cros_settings_names.h"
24 #include "components/crx_file/id_util.h"
25 #include "components/user_manager/user_manager.h"
26 #include "content/public/browser/web_ui.h"
27 #include "content/public/browser/web_ui_data_source.h"
28 #include "extensions/common/extension_urls.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/webui/web_ui_util.h"
31 #include "url/gurl.h"
33 namespace chromeos {
35 namespace {
37 // Populates app info dictionary with |app_data|.
38 void PopulateAppDict(const KioskAppManager::App& app_data,
39 base::DictionaryValue* app_dict) {
40 std::string icon_url("chrome://theme/IDR_APP_DEFAULT_ICON");
42 // TODO(xiyuan): Replace data url with a URLDataSource.
43 if (!app_data.icon.isNull())
44 icon_url = webui::GetBitmapDataUrl(*app_data.icon.bitmap());
46 // The items which are to be written into app_dict are also described in
47 // chrome/browser/resources/extensions/chromeos/kiosk_app_list.js in @typedef
48 // for AppDict. Please update it whenever you add or remove any keys here.
49 app_dict->SetString("id", app_data.app_id);
50 app_dict->SetString("name", app_data.name);
51 app_dict->SetString("iconURL", icon_url);
52 app_dict->SetBoolean(
53 "autoLaunch",
54 KioskAppManager::Get()->GetAutoLaunchApp() == app_data.app_id &&
55 (KioskAppManager::Get()->IsAutoLaunchEnabled() ||
56 KioskAppManager::Get()->IsAutoLaunchRequested()));
57 app_dict->SetBoolean("isLoading", app_data.is_loading);
60 // Sanitize app id input value and extracts app id out of it.
61 // Returns false if an app id could not be derived out of the input.
62 bool ExtractsAppIdFromInput(const std::string& input,
63 std::string* app_id) {
64 if (crx_file::id_util::IdIsValid(input)) {
65 *app_id = input;
66 return true;
69 GURL webstore_url = GURL(input);
70 if (!webstore_url.is_valid())
71 return false;
73 GURL webstore_base_url =
74 GURL(extension_urls::GetWebstoreItemDetailURLPrefix());
76 if (webstore_url.scheme() != webstore_base_url.scheme() ||
77 webstore_url.host() != webstore_base_url.host() ||
78 !base::StartsWith(webstore_url.path(), webstore_base_url.path(),
79 base::CompareCase::SENSITIVE)) {
80 return false;
83 const std::string path = webstore_url.path();
84 const size_t last_slash = path.rfind('/');
85 if (last_slash == std::string::npos)
86 return false;
88 const std::string candidate_id = path.substr(last_slash + 1);
89 if (!crx_file::id_util::IdIsValid(candidate_id))
90 return false;
92 *app_id = candidate_id;
93 return true;
96 } // namespace
98 KioskAppsHandler::KioskAppsHandler(OwnerSettingsServiceChromeOS* service)
99 : kiosk_app_manager_(KioskAppManager::Get()),
100 initialized_(false),
101 is_kiosk_enabled_(false),
102 is_auto_launch_enabled_(false),
103 owner_settings_service_(service),
104 weak_ptr_factory_(this) {
105 kiosk_app_manager_->AddObserver(this);
108 KioskAppsHandler::~KioskAppsHandler() {
109 kiosk_app_manager_->RemoveObserver(this);
112 void KioskAppsHandler::RegisterMessages() {
113 web_ui()->RegisterMessageCallback("initializeKioskAppSettings",
114 base::Bind(&KioskAppsHandler::HandleInitializeKioskAppSettings,
115 base::Unretained(this)));
116 web_ui()->RegisterMessageCallback("getKioskAppSettings",
117 base::Bind(&KioskAppsHandler::HandleGetKioskAppSettings,
118 base::Unretained(this)));
119 web_ui()->RegisterMessageCallback("addKioskApp",
120 base::Bind(&KioskAppsHandler::HandleAddKioskApp,
121 base::Unretained(this)));
122 web_ui()->RegisterMessageCallback("removeKioskApp",
123 base::Bind(&KioskAppsHandler::HandleRemoveKioskApp,
124 base::Unretained(this)));
125 web_ui()->RegisterMessageCallback("enableKioskAutoLaunch",
126 base::Bind(&KioskAppsHandler::HandleEnableKioskAutoLaunch,
127 base::Unretained(this)));
128 web_ui()->RegisterMessageCallback("disableKioskAutoLaunch",
129 base::Bind(&KioskAppsHandler::HandleDisableKioskAutoLaunch,
130 base::Unretained(this)));
131 web_ui()->RegisterMessageCallback("setDisableBailoutShortcut",
132 base::Bind(&KioskAppsHandler::HandleSetDisableBailoutShortcut,
133 base::Unretained(this)));
136 void KioskAppsHandler::GetLocalizedValues(content::WebUIDataSource* source) {
137 source->AddString(
138 "addKioskAppButton",
139 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ADD_KIOSK_APP_BUTTON));
140 source->AddString(
141 "kioskOverlayTitle",
142 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_OVERLAY_TITLE));
143 source->AddString(
144 "addKioskApp",
145 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP));
146 source->AddString(
147 "kioskAppIdEditHint",
148 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ADD_APP_HINT));
149 source->AddString(
150 "enableAutoLaunchButton",
151 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_ENABLE_AUTO_LAUNCH));
152 source->AddString(
153 "disableAutoLaunchButton",
154 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_DISABLE_AUTO_LAUNCH));
155 source->AddString(
156 "autoLaunch",
157 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_AUTO_LAUNCH));
158 source->AddString(
159 "invalidApp",
160 l10n_util::GetStringUTF16(IDS_OPTIONS_KIOSK_INVALID_APP));
161 source->AddString(
162 "kioskDiableBailoutShortcutLabel",
163 l10n_util::GetStringUTF16(
164 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_LABEL));
165 source->AddString(
166 "kioskDisableBailoutShortcutWarningBold",
167 l10n_util::GetStringUTF16(
168 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_BOLD));
169 const base::string16 product_os_name =
170 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME);
171 source->AddString(
172 "kioskDisableBailoutShortcutWarning",
173 l10n_util::GetStringFUTF16(
174 IDS_OPTIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_FORMAT,
175 product_os_name));
176 source->AddString(
177 "kioskDisableBailoutShortcutConfirm",
178 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL));
179 source->AddString(
180 "kioskDisableBailoutShortcutCancel",
181 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL));
182 source->AddString("done", l10n_util::GetStringUTF16(IDS_DONE));
183 source->AddString("add", l10n_util::GetStringUTF16(IDS_ADD));
186 void KioskAppsHandler::OnKioskAppDataChanged(const std::string& app_id) {
187 UpdateApp(app_id);
190 void KioskAppsHandler::OnKioskAppDataLoadFailure(const std::string& app_id) {
191 ShowError(app_id);
194 void KioskAppsHandler::OnKioskExtensionLoadedInCache(
195 const std::string& app_id) {
196 UpdateApp(app_id);
199 void KioskAppsHandler::OnKioskExtensionDownloadFailed(
200 const std::string& app_id) {
201 ShowError(app_id);
204 void KioskAppsHandler::OnGetConsumerKioskAutoLaunchStatus(
205 chromeos::KioskAppManager::ConsumerKioskAutoLaunchStatus status) {
206 initialized_ = true;
207 is_kiosk_enabled_ = user_manager::UserManager::Get()->IsCurrentUserOwner() ||
208 !base::SysInfo::IsRunningOnChromeOS();
210 is_auto_launch_enabled_ =
211 status == KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED ||
212 !base::SysInfo::IsRunningOnChromeOS();
214 if (is_kiosk_enabled_) {
215 base::DictionaryValue kiosk_params;
216 kiosk_params.SetBoolean("kioskEnabled", is_kiosk_enabled_);
217 kiosk_params.SetBoolean("autoLaunchEnabled", is_auto_launch_enabled_);
218 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.enableKiosk",
219 kiosk_params);
224 void KioskAppsHandler::OnKioskAppsSettingsChanged() {
225 SendKioskAppSettings();
228 void KioskAppsHandler::SendKioskAppSettings() {
229 if (!initialized_ || !is_kiosk_enabled_)
230 return;
232 bool enable_bailout_shortcut;
233 if (!CrosSettings::Get()->GetBoolean(
234 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
235 &enable_bailout_shortcut)) {
236 enable_bailout_shortcut = true;
239 base::DictionaryValue settings;
240 settings.SetBoolean("disableBailout", !enable_bailout_shortcut);
241 settings.SetBoolean("hasAutoLaunchApp",
242 !kiosk_app_manager_->GetAutoLaunchApp().empty());
244 KioskAppManager::Apps apps;
245 kiosk_app_manager_->GetApps(&apps);
247 scoped_ptr<base::ListValue> apps_list(new base::ListValue);
248 for (size_t i = 0; i < apps.size(); ++i) {
249 const KioskAppManager::App& app_data = apps[i];
251 scoped_ptr<base::DictionaryValue> app_info(new base::DictionaryValue);
252 PopulateAppDict(app_data, app_info.get());
253 apps_list->Append(app_info.release());
255 settings.SetWithoutPathExpansion("apps", apps_list.release());
257 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.setSettings",
258 settings);
261 void KioskAppsHandler::HandleInitializeKioskAppSettings(
262 const base::ListValue* args) {
263 KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
264 base::Bind(&KioskAppsHandler::OnGetConsumerKioskAutoLaunchStatus,
265 weak_ptr_factory_.GetWeakPtr()));
268 void KioskAppsHandler::HandleGetKioskAppSettings(const base::ListValue* args) {
269 SendKioskAppSettings();
273 void KioskAppsHandler::HandleAddKioskApp(const base::ListValue* args) {
274 if (!initialized_ || !is_kiosk_enabled_)
275 return;
277 std::string input;
278 CHECK(args->GetString(0, &input));
280 std::string app_id;
281 if (!ExtractsAppIdFromInput(input, &app_id)) {
282 OnKioskAppDataLoadFailure(input);
283 return;
286 kiosk_app_manager_->AddApp(app_id, owner_settings_service_);
289 void KioskAppsHandler::HandleRemoveKioskApp(const base::ListValue* args) {
290 if (!initialized_ || !is_kiosk_enabled_)
291 return;
293 std::string app_id;
294 CHECK(args->GetString(0, &app_id));
296 kiosk_app_manager_->RemoveApp(app_id, owner_settings_service_);
299 void KioskAppsHandler::HandleEnableKioskAutoLaunch(
300 const base::ListValue* args) {
301 if (!initialized_ || !is_kiosk_enabled_ || !is_auto_launch_enabled_)
302 return;
304 std::string app_id;
305 CHECK(args->GetString(0, &app_id));
307 kiosk_app_manager_->SetAutoLaunchApp(app_id, owner_settings_service_);
310 void KioskAppsHandler::HandleDisableKioskAutoLaunch(
311 const base::ListValue* args) {
312 if (!initialized_ || !is_kiosk_enabled_ || !is_auto_launch_enabled_)
313 return;
315 std::string app_id;
316 CHECK(args->GetString(0, &app_id));
318 std::string startup_app_id = kiosk_app_manager_->GetAutoLaunchApp();
319 if (startup_app_id != app_id)
320 return;
322 kiosk_app_manager_->SetAutoLaunchApp("", owner_settings_service_);
325 void KioskAppsHandler::HandleSetDisableBailoutShortcut(
326 const base::ListValue* args) {
327 if (!initialized_ || !is_kiosk_enabled_)
328 return;
330 bool disable_bailout_shortcut;
331 CHECK(args->GetBoolean(0, &disable_bailout_shortcut));
333 owner_settings_service_->SetBoolean(
334 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
335 !disable_bailout_shortcut);
338 void KioskAppsHandler::UpdateApp(const std::string& app_id) {
339 KioskAppManager::App app_data;
340 if (!kiosk_app_manager_->GetApp(app_id, &app_data))
341 return;
343 base::DictionaryValue app_dict;
344 PopulateAppDict(app_data, &app_dict);
346 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.updateApp",
347 app_dict);
350 void KioskAppsHandler::ShowError(const std::string& app_id) {
351 base::StringValue app_id_value(app_id);
352 web_ui()->CallJavascriptFunction("extensions.KioskAppsOverlay.showError",
353 app_id_value);
355 kiosk_app_manager_->RemoveApp(app_id, owner_settings_service_);
358 } // namespace chromeos