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