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.
4
5 #include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h"
6
7 #include "ash/magnifier/magnifier_constants.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/values.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
13 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
14 #include "chrome/browser/chromeos/login/wizard_controller.h"
15 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
16 #include "chrome/browser/chromeos/system/input_device_settings.h"
17 #include "chrome/browser/lifetime/application_lifetime.h"
18 #include "chrome/browser/policy/browser_policy_connector.h"
19 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
20 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
21 #include "chrome/common/chrome_constants.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "chromeos/chromeos_constants.h"
24 #include "content/public/browser/notification_service.h"
25 #include "grit/chromium_strings.h"
26 #include "grit/generated_resources.h"
27
28 namespace {
29
30 const char kJsScreenPath[] = "cr.ui.Oobe";
31
32 // JS API callbacks names.
33 const char kJsApiEnableHighContrast[] = "enableHighContrast";
34 const char kJsApiEnableScreenMagnifier[] = "enableScreenMagnifier";
35 const char kJsApiEnableLargeCursor[] = "enableLargeCursor";
36 const char kJsApiEnableSpokenFeedback[] = "enableSpokenFeedback";
37 const char kJsApiScreenStateInitialize[] = "screenStateInitialize";
38 const char kJsApiSkipUpdateEnrollAfterEula[] = "skipUpdateEnrollAfterEula";
39 const char kJsApiScreenAssetsLoaded[] = "screenAssetsLoaded";
40
41 } // namespace
42
43 namespace chromeos {
44
45 // Note that show_oobe_ui_ defaults to false because WizardController assumes
46 // OOBE UI is not visible by default.
CoreOobeHandler(OobeUI * oobe_ui)47 CoreOobeHandler::CoreOobeHandler(OobeUI* oobe_ui)
48 : BaseScreenHandler(kJsScreenPath),
49 oobe_ui_(oobe_ui),
50 show_oobe_ui_(false),
51 version_info_updater_(this),
52 delegate_(NULL) {
53 registrar_.Add(
54 this,
55 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
56 content::NotificationService::AllSources());
57 registrar_.Add(
58 this,
59 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
60 content::NotificationService::AllSources());
61 registrar_.Add(
62 this,
63 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
64 content::NotificationService::AllSources());
65 registrar_.Add(
66 this,
67 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_LARGE_CURSOR,
68 content::NotificationService::AllSources());
69 }
70
~CoreOobeHandler()71 CoreOobeHandler::~CoreOobeHandler() {
72 }
73
SetDelegate(Delegate * delegate)74 void CoreOobeHandler::SetDelegate(Delegate* delegate) {
75 delegate_ = delegate;
76 }
77
DeclareLocalizedValues(LocalizedValuesBuilder * builder)78 void CoreOobeHandler::DeclareLocalizedValues(LocalizedValuesBuilder* builder) {
79 builder->Add("title", IDS_SHORT_PRODUCT_NAME);
80 builder->Add("productName", IDS_SHORT_PRODUCT_NAME);
81 builder->Add("learnMore", IDS_LEARN_MORE);
82
83 // OOBE accessibility options menu strings shown on each screen.
84 builder->Add("accessibilityLink", IDS_OOBE_ACCESSIBILITY_LINK);
85 builder->Add("spokenFeedbackOption", IDS_OOBE_SPOKEN_FEEDBACK_OPTION);
86 builder->Add("largeCursorOption", IDS_OOBE_LARGE_CURSOR_OPTION);
87 builder->Add("highContrastOption", IDS_OOBE_HIGH_CONTRAST_MODE_OPTION);
88 builder->Add("screenMagnifierOption", IDS_OOBE_SCREEN_MAGNIFIER_OPTION);
89
90 // Strings for the device requisition prompt.
91 builder->Add("deviceRequisitionPromptCancel",
92 IDS_ENTERPRISE_DEVICE_REQUISITION_PROMPT_CANCEL);
93 builder->Add("deviceRequisitionPromptOk",
94 IDS_ENTERPRISE_DEVICE_REQUISITION_PROMPT_OK);
95 builder->Add("deviceRequisitionPromptText",
96 IDS_ENTERPRISE_DEVICE_REQUISITION_PROMPT_TEXT);
97 builder->Add("deviceRequisitionRemoraPromptCancel",
98 IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
99 builder->Add("deviceRequisitionRemoraPromptOk",
100 IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
101 builder->Add("deviceRequisitionRemoraPromptTitle",
102 IDS_ENTERPRISE_DEVICE_REQUISITION_REMORA_PROMPT_TITLE);
103 builder->Add("deviceRequisitionRemoraPromptText",
104 IDS_ENTERPRISE_DEVICE_REQUISITION_REMORA_PROMPT_TEXT);
105 }
106
Initialize()107 void CoreOobeHandler::Initialize() {
108 UpdateA11yState();
109 UpdateOobeUIVisibility();
110 #if defined(OFFICIAL_BUILD)
111 version_info_updater_.StartUpdate(true);
112 #else
113 version_info_updater_.StartUpdate(false);
114 #endif
115 UpdateDeviceRequisition();
116 }
117
RegisterMessages()118 void CoreOobeHandler::RegisterMessages() {
119 AddCallback(kJsApiScreenStateInitialize,
120 &CoreOobeHandler::HandleInitialized);
121 AddCallback(kJsApiSkipUpdateEnrollAfterEula,
122 &CoreOobeHandler::HandleSkipUpdateEnrollAfterEula);
123 AddCallback("updateCurrentScreen",
124 &CoreOobeHandler::HandleUpdateCurrentScreen);
125 AddCallback(kJsApiEnableHighContrast,
126 &CoreOobeHandler::HandleEnableHighContrast);
127 AddCallback(kJsApiEnableLargeCursor,
128 &CoreOobeHandler::HandleEnableLargeCursor);
129 AddCallback(kJsApiEnableScreenMagnifier,
130 &CoreOobeHandler::HandleEnableScreenMagnifier);
131 AddCallback(kJsApiEnableSpokenFeedback,
132 &CoreOobeHandler::HandleEnableSpokenFeedback);
133 AddCallback("setDeviceRequisition",
134 &CoreOobeHandler::HandleSetDeviceRequisition);
135 AddCallback(kJsApiScreenAssetsLoaded,
136 &CoreOobeHandler::HandleScreenAssetsLoaded);
137 AddRawCallback("skipToLoginForTesting",
138 &CoreOobeHandler::HandleSkipToLoginForTesting);
139 }
140
ShowSignInError(int login_attempts,const std::string & error_text,const std::string & help_link_text,HelpAppLauncher::HelpTopic help_topic_id)141 void CoreOobeHandler::ShowSignInError(
142 int login_attempts,
143 const std::string& error_text,
144 const std::string& help_link_text,
145 HelpAppLauncher::HelpTopic help_topic_id) {
146 LOG(ERROR) << "CoreOobeHandler::ShowSignInError: error_text=" << error_text;
147 CallJS("showSignInError", login_attempts, error_text,
148 help_link_text, static_cast<int>(help_topic_id));
149 }
150
ShowTpmError()151 void CoreOobeHandler::ShowTpmError() {
152 CallJS("showTpmError");
153 }
154
ShowSignInUI(const std::string & email)155 void CoreOobeHandler::ShowSignInUI(const std::string& email) {
156 CallJS("showSigninUI", email);
157 }
158
ResetSignInUI(bool force_online)159 void CoreOobeHandler::ResetSignInUI(bool force_online) {
160 CallJS("resetSigninUI", force_online);
161 }
162
ClearUserPodPassword()163 void CoreOobeHandler::ClearUserPodPassword() {
164 CallJS("clearUserPodPassword");
165 }
166
RefocusCurrentPod()167 void CoreOobeHandler::RefocusCurrentPod() {
168 CallJS("refocusCurrentPod");
169 }
170
OnLoginSuccess(const std::string & username)171 void CoreOobeHandler::OnLoginSuccess(const std::string& username) {
172 CallJS("onLoginSuccess", username);
173 }
174
ShowPasswordChangedScreen(bool show_password_error)175 void CoreOobeHandler::ShowPasswordChangedScreen(bool show_password_error) {
176 CallJS("showPasswordChangedScreen", show_password_error);
177 }
178
SetUsageStats(bool checked)179 void CoreOobeHandler::SetUsageStats(bool checked) {
180 CallJS("setUsageStats", checked);
181 }
182
SetOemEulaUrl(const std::string & oem_eula_url)183 void CoreOobeHandler::SetOemEulaUrl(const std::string& oem_eula_url) {
184 CallJS("setOemEulaUrl", oem_eula_url);
185 }
186
SetTpmPassword(const std::string & tpm_password)187 void CoreOobeHandler::SetTpmPassword(const std::string& tpm_password) {
188 CallJS("setTpmPassword", tpm_password);
189 }
190
ClearErrors()191 void CoreOobeHandler::ClearErrors() {
192 CallJS("clearErrors");
193 }
194
ReloadContent(const base::DictionaryValue & dictionary)195 void CoreOobeHandler::ReloadContent(const base::DictionaryValue& dictionary) {
196 CallJS("reloadContent", dictionary);
197 }
198
HandleInitialized()199 void CoreOobeHandler::HandleInitialized() {
200 oobe_ui_->InitializeHandlers();
201 }
202
HandleSkipUpdateEnrollAfterEula()203 void CoreOobeHandler::HandleSkipUpdateEnrollAfterEula() {
204 WizardController* controller = WizardController::default_controller();
205 DCHECK(controller);
206 if (controller)
207 controller->SkipUpdateEnrollAfterEula();
208 }
209
HandleUpdateCurrentScreen(const std::string & screen)210 void CoreOobeHandler::HandleUpdateCurrentScreen(const std::string& screen) {
211 if (delegate_)
212 delegate_->OnCurrentScreenChanged(screen);
213 }
214
HandleEnableHighContrast(bool enabled)215 void CoreOobeHandler::HandleEnableHighContrast(bool enabled) {
216 AccessibilityManager::Get()->EnableHighContrast(enabled);
217 }
218
HandleEnableLargeCursor(bool enabled)219 void CoreOobeHandler::HandleEnableLargeCursor(bool enabled) {
220 AccessibilityManager::Get()->EnableLargeCursor(enabled);
221 }
222
HandleEnableScreenMagnifier(bool enabled)223 void CoreOobeHandler::HandleEnableScreenMagnifier(bool enabled) {
224 // TODO(nkostylev): Add support for partial screen magnifier.
225 DCHECK(MagnificationManager::Get());
226 MagnificationManager::Get()->SetMagnifierEnabled(enabled);
227 }
228
HandleEnableSpokenFeedback()229 void CoreOobeHandler::HandleEnableSpokenFeedback() {
230 // Checkbox is initialized on page init and updates when spoken feedback
231 // setting is changed so just toggle spoken feedback here.
232 AccessibilityManager::Get()->ToggleSpokenFeedback(
233 ash::A11Y_NOTIFICATION_NONE);
234 }
235
HandleSetDeviceRequisition(const std::string & requisition)236 void CoreOobeHandler::HandleSetDeviceRequisition(
237 const std::string& requisition) {
238 policy::BrowserPolicyConnector* connector =
239 g_browser_process->browser_policy_connector();
240 std::string initial_requisition =
241 connector->GetDeviceCloudPolicyManager()->GetDeviceRequisition();
242 connector->GetDeviceCloudPolicyManager()->SetDeviceRequisition(requisition);
243 // Exit Chrome to force the restart as soon as a new requisition is set.
244 if (initial_requisition !=
245 connector->GetDeviceCloudPolicyManager()->GetDeviceRequisition()) {
246 chrome::AttemptRestart();
247 }
248 }
249
HandleScreenAssetsLoaded(const std::string & screen_async_load_id)250 void CoreOobeHandler::HandleScreenAssetsLoaded(
251 const std::string& screen_async_load_id) {
252 oobe_ui_->OnScreenAssetsLoaded(screen_async_load_id);
253 }
254
HandleSkipToLoginForTesting(const base::ListValue * args)255 void CoreOobeHandler::HandleSkipToLoginForTesting(
256 const base::ListValue* args) {
257 LoginScreenContext context(args);
258 if (WizardController::default_controller())
259 WizardController::default_controller()->SkipToLoginForTesting(context);
260 }
261
ShowOobeUI(bool show)262 void CoreOobeHandler::ShowOobeUI(bool show) {
263 if (show == show_oobe_ui_)
264 return;
265
266 show_oobe_ui_ = show;
267
268 if (page_is_ready())
269 UpdateOobeUIVisibility();
270 }
271
UpdateA11yState()272 void CoreOobeHandler::UpdateA11yState() {
273 DCHECK(MagnificationManager::Get());
274 base::DictionaryValue a11y_info;
275 a11y_info.SetBoolean("highContrastEnabled",
276 AccessibilityManager::Get()->IsHighContrastEnabled());
277 a11y_info.SetBoolean("largeCursorEnabled",
278 AccessibilityManager::Get()->IsLargeCursorEnabled());
279 a11y_info.SetBoolean("spokenFeedbackEnabled",
280 AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
281 a11y_info.SetBoolean("screenMagnifierEnabled",
282 MagnificationManager::Get()->IsMagnifierEnabled());
283 CallJS("refreshA11yInfo", a11y_info);
284 }
285
UpdateOobeUIVisibility()286 void CoreOobeHandler::UpdateOobeUIVisibility() {
287 // Don't show version label on the stable channel by default.
288 bool should_show_version = true;
289 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
290 if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
291 channel == chrome::VersionInfo::CHANNEL_BETA) {
292 should_show_version = false;
293 }
294 CallJS("showVersion", should_show_version);
295 CallJS("showOobeUI", show_oobe_ui_);
296 if (system::keyboard_settings::ForceKeyboardDrivenUINavigation())
297 CallJS("enableKeyboardFlow", true);
298 }
299
OnOSVersionLabelTextUpdated(const std::string & os_version_label_text)300 void CoreOobeHandler::OnOSVersionLabelTextUpdated(
301 const std::string& os_version_label_text) {
302 UpdateLabel("version", os_version_label_text);
303 }
304
OnEnterpriseInfoUpdated(const std::string & message_text)305 void CoreOobeHandler::OnEnterpriseInfoUpdated(
306 const std::string& message_text) {
307 CallJS("setEnterpriseInfo", message_text);
308 }
309
UpdateLabel(const std::string & id,const std::string & text)310 void CoreOobeHandler::UpdateLabel(const std::string& id,
311 const std::string& text) {
312 CallJS("setLabelText", id, text);
313 }
314
UpdateDeviceRequisition()315 void CoreOobeHandler::UpdateDeviceRequisition() {
316 CallJS("updateDeviceRequisition",
317 g_browser_process->browser_policy_connector()->
318 GetDeviceCloudPolicyManager()->GetDeviceRequisition());
319 }
320
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)321 void CoreOobeHandler::Observe(int type,
322 const content::NotificationSource& source,
323 const content::NotificationDetails& details) {
324 if (type ==
325 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE ||
326 type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_LARGE_CURSOR ||
327 type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER ||
328 type == chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) {
329 UpdateA11yState();
330 } else {
331 NOTREACHED() << "Unexpected notification " << type;
332 }
333 }
334
335 } // namespace chromeos
336