• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ash/shell.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/values.h"
11 #include "chrome/browser/browser_process.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/helper.h"
15 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
16 #include "chrome/browser/chromeos/login/wizard_controller.h"
17 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
18 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
19 #include "chrome/browser/chromeos/system/input_device_settings.h"
20 #include "chrome/browser/lifetime/application_lifetime.h"
21 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
22 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
23 #include "chrome/common/chrome_constants.h"
24 #include "chrome/common/chrome_version_info.h"
25 #include "chromeos/chromeos_constants.h"
26 #include "grit/chromium_strings.h"
27 #include "grit/generated_resources.h"
28 #include "ui/gfx/display.h"
29 #include "ui/gfx/screen.h"
30 #include "ui/gfx/size.h"
31 #include "ui/keyboard/keyboard_controller.h"
32 
33 namespace {
34 
35 const char kJsScreenPath[] = "cr.ui.Oobe";
36 
37 // JS API callbacks names.
38 const char kJsApiEnableHighContrast[] = "enableHighContrast";
39 const char kJsApiEnableVirtualKeyboard[] = "enableVirtualKeyboard";
40 const char kJsApiEnableScreenMagnifier[] = "enableScreenMagnifier";
41 const char kJsApiEnableLargeCursor[] = "enableLargeCursor";
42 const char kJsApiEnableSpokenFeedback[] = "enableSpokenFeedback";
43 const char kJsApiScreenStateInitialize[] = "screenStateInitialize";
44 const char kJsApiSkipUpdateEnrollAfterEula[] = "skipUpdateEnrollAfterEula";
45 const char kJsApiScreenAssetsLoaded[] = "screenAssetsLoaded";
46 const char kJsApiHeaderBarVisible[] = "headerBarVisible";
47 
48 }  // namespace
49 
50 namespace chromeos {
51 
52 // Note that show_oobe_ui_ defaults to false because WizardController assumes
53 // OOBE UI is not visible by default.
CoreOobeHandler(OobeUI * oobe_ui)54 CoreOobeHandler::CoreOobeHandler(OobeUI* oobe_ui)
55     : BaseScreenHandler(kJsScreenPath),
56       oobe_ui_(oobe_ui),
57       show_oobe_ui_(false),
58       version_info_updater_(this),
59       delegate_(NULL) {
60   AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
61   CHECK(accessibility_manager);
62   accessibility_subscription_ = accessibility_manager->RegisterCallback(
63       base::Bind(&CoreOobeHandler::OnAccessibilityStatusChanged,
64                  base::Unretained(this)));
65 }
66 
~CoreOobeHandler()67 CoreOobeHandler::~CoreOobeHandler() {
68 }
69 
SetDelegate(Delegate * delegate)70 void CoreOobeHandler::SetDelegate(Delegate* delegate) {
71   delegate_ = delegate;
72 }
73 
DeclareLocalizedValues(LocalizedValuesBuilder * builder)74 void CoreOobeHandler::DeclareLocalizedValues(LocalizedValuesBuilder* builder) {
75   builder->Add("title", IDS_SHORT_PRODUCT_NAME);
76   builder->Add("productName", IDS_SHORT_PRODUCT_NAME);
77   builder->Add("learnMore", IDS_LEARN_MORE);
78 
79   // OOBE accessibility options menu strings shown on each screen.
80   builder->Add("accessibilityLink", IDS_OOBE_ACCESSIBILITY_LINK);
81   builder->Add("spokenFeedbackOption", IDS_OOBE_SPOKEN_FEEDBACK_OPTION);
82   builder->Add("largeCursorOption", IDS_OOBE_LARGE_CURSOR_OPTION);
83   builder->Add("highContrastOption", IDS_OOBE_HIGH_CONTRAST_MODE_OPTION);
84   builder->Add("screenMagnifierOption", IDS_OOBE_SCREEN_MAGNIFIER_OPTION);
85   builder->Add("virtualKeyboardOption", IDS_OOBE_VIRTUAL_KEYBOARD_OPTION);
86   builder->Add("closeAccessibilityMenu", IDS_OOBE_CLOSE_ACCESSIBILITY_MENU);
87 
88   // Strings for the device requisition prompt.
89   builder->Add("deviceRequisitionPromptCancel",
90                IDS_ENTERPRISE_DEVICE_REQUISITION_PROMPT_CANCEL);
91   builder->Add("deviceRequisitionPromptOk",
92                IDS_ENTERPRISE_DEVICE_REQUISITION_PROMPT_OK);
93   builder->Add("deviceRequisitionPromptText",
94                IDS_ENTERPRISE_DEVICE_REQUISITION_PROMPT_TEXT);
95   builder->Add("deviceRequisitionRemoraPromptCancel",
96                IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
97   builder->Add("deviceRequisitionRemoraPromptOk",
98                IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
99   builder->Add("deviceRequisitionRemoraPromptText",
100                IDS_ENTERPRISE_DEVICE_REQUISITION_REMORA_PROMPT_TEXT);
101 }
102 
Initialize()103 void CoreOobeHandler::Initialize() {
104   UpdateA11yState();
105   UpdateOobeUIVisibility();
106 #if defined(OFFICIAL_BUILD)
107   version_info_updater_.StartUpdate(true);
108 #else
109   version_info_updater_.StartUpdate(false);
110 #endif
111   UpdateDeviceRequisition();
112   UpdateKeyboardState();
113   UpdateClientAreaSize();
114 }
115 
RegisterMessages()116 void CoreOobeHandler::RegisterMessages() {
117   AddCallback(kJsApiScreenStateInitialize,
118               &CoreOobeHandler::HandleInitialized);
119   AddCallback(kJsApiSkipUpdateEnrollAfterEula,
120               &CoreOobeHandler::HandleSkipUpdateEnrollAfterEula);
121   AddCallback("updateCurrentScreen",
122               &CoreOobeHandler::HandleUpdateCurrentScreen);
123   AddCallback(kJsApiEnableHighContrast,
124               &CoreOobeHandler::HandleEnableHighContrast);
125   AddCallback(kJsApiEnableLargeCursor,
126               &CoreOobeHandler::HandleEnableLargeCursor);
127   AddCallback(kJsApiEnableVirtualKeyboard,
128               &CoreOobeHandler::HandleEnableVirtualKeyboard);
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   AddCallback("launchHelpApp",
140               &CoreOobeHandler::HandleLaunchHelpApp);
141   AddCallback("toggleResetScreen", &CoreOobeHandler::HandleToggleResetScreen);
142   AddCallback(kJsApiHeaderBarVisible,
143               &CoreOobeHandler::HandleHeaderBarVisible);
144 }
145 
ShowSignInError(int login_attempts,const std::string & error_text,const std::string & help_link_text,HelpAppLauncher::HelpTopic help_topic_id)146 void CoreOobeHandler::ShowSignInError(
147     int login_attempts,
148     const std::string& error_text,
149     const std::string& help_link_text,
150     HelpAppLauncher::HelpTopic help_topic_id) {
151   LOG(ERROR) << "CoreOobeHandler::ShowSignInError: error_text=" << error_text;
152   CallJS("showSignInError", login_attempts, error_text,
153          help_link_text, static_cast<int>(help_topic_id));
154 }
155 
ShowTpmError()156 void CoreOobeHandler::ShowTpmError() {
157   CallJS("showTpmError");
158 }
159 
ShowDeviceResetScreen()160 void CoreOobeHandler::ShowDeviceResetScreen() {
161   policy::BrowserPolicyConnectorChromeOS* connector =
162       g_browser_process->platform_part()->browser_policy_connector_chromeos();
163   if (!connector->IsEnterpriseManaged()) {
164     // Don't recreate WizardController if it already exists.
165     WizardController* wizard_controller =
166         WizardController::default_controller();
167     if (wizard_controller && !wizard_controller->login_screen_started()) {
168       wizard_controller->AdvanceToScreen(WizardController::kResetScreenName);
169     } else {
170       scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
171       DCHECK(LoginDisplayHostImpl::default_host());
172       if (LoginDisplayHostImpl::default_host()) {
173         LoginDisplayHostImpl::default_host()->StartWizard(
174             WizardController::kResetScreenName, params.Pass());
175       }
176     }
177   }
178 }
179 
ShowSignInUI(const std::string & email)180 void CoreOobeHandler::ShowSignInUI(const std::string& email) {
181   CallJS("showSigninUI", email);
182 }
183 
ResetSignInUI(bool force_online)184 void CoreOobeHandler::ResetSignInUI(bool force_online) {
185   CallJS("resetSigninUI", force_online);
186 }
187 
ClearUserPodPassword()188 void CoreOobeHandler::ClearUserPodPassword() {
189   CallJS("clearUserPodPassword");
190 }
191 
RefocusCurrentPod()192 void CoreOobeHandler::RefocusCurrentPod() {
193   CallJS("refocusCurrentPod");
194 }
195 
ShowPasswordChangedScreen(bool show_password_error)196 void CoreOobeHandler::ShowPasswordChangedScreen(bool show_password_error) {
197   CallJS("showPasswordChangedScreen", show_password_error);
198 }
199 
SetUsageStats(bool checked)200 void CoreOobeHandler::SetUsageStats(bool checked) {
201   CallJS("setUsageStats", checked);
202 }
203 
SetOemEulaUrl(const std::string & oem_eula_url)204 void CoreOobeHandler::SetOemEulaUrl(const std::string& oem_eula_url) {
205   CallJS("setOemEulaUrl", oem_eula_url);
206 }
207 
SetTpmPassword(const std::string & tpm_password)208 void CoreOobeHandler::SetTpmPassword(const std::string& tpm_password) {
209   CallJS("setTpmPassword", tpm_password);
210 }
211 
ClearErrors()212 void CoreOobeHandler::ClearErrors() {
213   CallJS("clearErrors");
214 }
215 
ReloadContent(const base::DictionaryValue & dictionary)216 void CoreOobeHandler::ReloadContent(const base::DictionaryValue& dictionary) {
217   CallJS("reloadContent", dictionary);
218 }
219 
ShowControlBar(bool show)220 void CoreOobeHandler::ShowControlBar(bool show) {
221   CallJS("showControlBar", show);
222 }
223 
SetKeyboardState(bool shown,const gfx::Rect & bounds)224 void CoreOobeHandler::SetKeyboardState(bool shown, const gfx::Rect& bounds) {
225   CallJS("setKeyboardState", shown, bounds.width(), bounds.height());
226 }
227 
SetClientAreaSize(int width,int height)228 void CoreOobeHandler::SetClientAreaSize(int width, int height) {
229   CallJS("setClientAreaSize", width, height);
230 }
231 
HandleInitialized()232 void CoreOobeHandler::HandleInitialized() {
233   oobe_ui_->InitializeHandlers();
234 }
235 
HandleSkipUpdateEnrollAfterEula()236 void CoreOobeHandler::HandleSkipUpdateEnrollAfterEula() {
237   WizardController* controller = WizardController::default_controller();
238   DCHECK(controller);
239   if (controller)
240     controller->SkipUpdateEnrollAfterEula();
241 }
242 
HandleUpdateCurrentScreen(const std::string & screen)243 void CoreOobeHandler::HandleUpdateCurrentScreen(const std::string& screen) {
244   if (delegate_)
245     delegate_->OnCurrentScreenChanged(screen);
246 }
247 
HandleEnableHighContrast(bool enabled)248 void CoreOobeHandler::HandleEnableHighContrast(bool enabled) {
249   AccessibilityManager::Get()->EnableHighContrast(enabled);
250 }
251 
HandleEnableLargeCursor(bool enabled)252 void CoreOobeHandler::HandleEnableLargeCursor(bool enabled) {
253   AccessibilityManager::Get()->EnableLargeCursor(enabled);
254 }
255 
HandleEnableVirtualKeyboard(bool enabled)256 void CoreOobeHandler::HandleEnableVirtualKeyboard(bool enabled) {
257   AccessibilityManager::Get()->EnableVirtualKeyboard(enabled);
258 }
259 
HandleEnableScreenMagnifier(bool enabled)260 void CoreOobeHandler::HandleEnableScreenMagnifier(bool enabled) {
261   // TODO(nkostylev): Add support for partial screen magnifier.
262   DCHECK(MagnificationManager::Get());
263   MagnificationManager::Get()->SetMagnifierEnabled(enabled);
264 }
265 
HandleEnableSpokenFeedback()266 void CoreOobeHandler::HandleEnableSpokenFeedback() {
267   // Checkbox is initialized on page init and updates when spoken feedback
268   // setting is changed so just toggle spoken feedback here.
269   AccessibilityManager::Get()->ToggleSpokenFeedback(
270       ash::A11Y_NOTIFICATION_NONE);
271 }
272 
HandleSetDeviceRequisition(const std::string & requisition)273 void CoreOobeHandler::HandleSetDeviceRequisition(
274     const std::string& requisition) {
275   policy::BrowserPolicyConnectorChromeOS* connector =
276       g_browser_process->platform_part()->browser_policy_connector_chromeos();
277   std::string initial_requisition =
278       connector->GetDeviceCloudPolicyManager()->GetDeviceRequisition();
279   connector->GetDeviceCloudPolicyManager()->SetDeviceRequisition(requisition);
280   // Exit Chrome to force the restart as soon as a new requisition is set.
281   if (initial_requisition !=
282           connector->GetDeviceCloudPolicyManager()->GetDeviceRequisition()) {
283     chrome::AttemptRestart();
284   }
285 }
286 
HandleScreenAssetsLoaded(const std::string & screen_async_load_id)287 void CoreOobeHandler::HandleScreenAssetsLoaded(
288     const std::string& screen_async_load_id) {
289   oobe_ui_->OnScreenAssetsLoaded(screen_async_load_id);
290 }
291 
HandleSkipToLoginForTesting(const base::ListValue * args)292 void CoreOobeHandler::HandleSkipToLoginForTesting(
293     const base::ListValue* args) {
294   LoginScreenContext context(args);
295   if (WizardController::default_controller())
296       WizardController::default_controller()->SkipToLoginForTesting(context);
297 }
298 
HandleToggleResetScreen()299 void CoreOobeHandler::HandleToggleResetScreen() { ShowDeviceResetScreen(); }
300 
ShowOobeUI(bool show)301 void CoreOobeHandler::ShowOobeUI(bool show) {
302   if (show == show_oobe_ui_)
303     return;
304 
305   show_oobe_ui_ = show;
306 
307   if (page_is_ready())
308     UpdateOobeUIVisibility();
309 }
310 
UpdateA11yState()311 void CoreOobeHandler::UpdateA11yState() {
312   DCHECK(MagnificationManager::Get());
313   base::DictionaryValue a11y_info;
314   a11y_info.SetBoolean("highContrastEnabled",
315                        AccessibilityManager::Get()->IsHighContrastEnabled());
316   a11y_info.SetBoolean("largeCursorEnabled",
317                        AccessibilityManager::Get()->IsLargeCursorEnabled());
318   a11y_info.SetBoolean("spokenFeedbackEnabled",
319                        AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
320   a11y_info.SetBoolean("screenMagnifierEnabled",
321                        MagnificationManager::Get()->IsMagnifierEnabled());
322   a11y_info.SetBoolean("virtualKeyboardEnabled",
323                        AccessibilityManager::Get()->IsVirtualKeyboardEnabled());
324   CallJS("refreshA11yInfo", a11y_info);
325 }
326 
UpdateOobeUIVisibility()327 void CoreOobeHandler::UpdateOobeUIVisibility() {
328   // Don't show version label on the stable channel by default.
329   bool should_show_version = true;
330   chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
331   if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
332       channel == chrome::VersionInfo::CHANNEL_BETA) {
333     should_show_version = false;
334   }
335   CallJS("showVersion", should_show_version);
336   CallJS("showOobeUI", show_oobe_ui_);
337   if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation())
338     CallJS("enableKeyboardFlow", true);
339 }
340 
OnOSVersionLabelTextUpdated(const std::string & os_version_label_text)341 void CoreOobeHandler::OnOSVersionLabelTextUpdated(
342     const std::string& os_version_label_text) {
343   UpdateLabel("version", os_version_label_text);
344 }
345 
OnEnterpriseInfoUpdated(const std::string & message_text)346 void CoreOobeHandler::OnEnterpriseInfoUpdated(
347     const std::string& message_text) {
348   CallJS("setEnterpriseInfo", message_text);
349 }
350 
UpdateLabel(const std::string & id,const std::string & text)351 void CoreOobeHandler::UpdateLabel(const std::string& id,
352                                   const std::string& text) {
353   CallJS("setLabelText", id, text);
354 }
355 
UpdateDeviceRequisition()356 void CoreOobeHandler::UpdateDeviceRequisition() {
357   policy::BrowserPolicyConnectorChromeOS* connector =
358       g_browser_process->platform_part()->browser_policy_connector_chromeos();
359   CallJS("updateDeviceRequisition",
360          connector->GetDeviceCloudPolicyManager()->GetDeviceRequisition());
361 }
362 
UpdateKeyboardState()363 void CoreOobeHandler::UpdateKeyboardState() {
364   if (!login::LoginScrollIntoViewEnabled())
365     return;
366 
367   keyboard::KeyboardController* keyboard_controller =
368       keyboard::KeyboardController::GetInstance();
369   if (keyboard_controller) {
370     gfx::Rect bounds = keyboard_controller->current_keyboard_bounds();
371     SetKeyboardState(!bounds.IsEmpty(), bounds);
372   }
373 }
374 
UpdateClientAreaSize()375 void CoreOobeHandler::UpdateClientAreaSize() {
376   const gfx::Size& size = ash::Shell::GetScreen()->GetPrimaryDisplay().size();
377   SetClientAreaSize(size.width(), size.height());
378 }
379 
OnAccessibilityStatusChanged(const AccessibilityStatusEventDetails & details)380 void CoreOobeHandler::OnAccessibilityStatusChanged(
381     const AccessibilityStatusEventDetails& details) {
382   if (details.notification_type == ACCESSIBILITY_MANAGER_SHUTDOWN)
383     accessibility_subscription_.reset();
384   else
385     UpdateA11yState();
386 }
387 
HandleLaunchHelpApp(double help_topic_id)388 void CoreOobeHandler::HandleLaunchHelpApp(double help_topic_id) {
389   if (!help_app_)
390     help_app_ = new HelpAppLauncher(GetNativeWindow());
391   help_app_->ShowHelpTopic(
392       static_cast<HelpAppLauncher::HelpTopic>(help_topic_id));
393 }
394 
HandleHeaderBarVisible()395 void CoreOobeHandler::HandleHeaderBarVisible() {
396   LoginDisplayHost* login_display_host = LoginDisplayHostImpl::default_host();
397   if (login_display_host)
398     login_display_host->SetStatusAreaVisible(true);
399 }
400 
InitDemoModeDetection()401 void CoreOobeHandler::InitDemoModeDetection() {
402   demo_mode_detector_.InitDetection();
403 }
404 
StopDemoModeDetection()405 void CoreOobeHandler::StopDemoModeDetection() {
406   demo_mode_detector_.StopDetection();
407 }
408 
409 }  // namespace chromeos
410