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 "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.
     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 
     67 CoreOobeHandler::~CoreOobeHandler() {
     68 }
     69 
     70 void CoreOobeHandler::SetDelegate(Delegate* delegate) {
     71   delegate_ = delegate;
     72 }
     73 
     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 
    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 
    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 
    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 
    156 void CoreOobeHandler::ShowTpmError() {
    157   CallJS("showTpmError");
    158 }
    159 
    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 
    180 void CoreOobeHandler::ShowSignInUI(const std::string& email) {
    181   CallJS("showSigninUI", email);
    182 }
    183 
    184 void CoreOobeHandler::ResetSignInUI(bool force_online) {
    185   CallJS("resetSigninUI", force_online);
    186 }
    187 
    188 void CoreOobeHandler::ClearUserPodPassword() {
    189   CallJS("clearUserPodPassword");
    190 }
    191 
    192 void CoreOobeHandler::RefocusCurrentPod() {
    193   CallJS("refocusCurrentPod");
    194 }
    195 
    196 void CoreOobeHandler::ShowPasswordChangedScreen(bool show_password_error) {
    197   CallJS("showPasswordChangedScreen", show_password_error);
    198 }
    199 
    200 void CoreOobeHandler::SetUsageStats(bool checked) {
    201   CallJS("setUsageStats", checked);
    202 }
    203 
    204 void CoreOobeHandler::SetOemEulaUrl(const std::string& oem_eula_url) {
    205   CallJS("setOemEulaUrl", oem_eula_url);
    206 }
    207 
    208 void CoreOobeHandler::SetTpmPassword(const std::string& tpm_password) {
    209   CallJS("setTpmPassword", tpm_password);
    210 }
    211 
    212 void CoreOobeHandler::ClearErrors() {
    213   CallJS("clearErrors");
    214 }
    215 
    216 void CoreOobeHandler::ReloadContent(const base::DictionaryValue& dictionary) {
    217   CallJS("reloadContent", dictionary);
    218 }
    219 
    220 void CoreOobeHandler::ShowControlBar(bool show) {
    221   CallJS("showControlBar", show);
    222 }
    223 
    224 void CoreOobeHandler::SetKeyboardState(bool shown, const gfx::Rect& bounds) {
    225   CallJS("setKeyboardState", shown, bounds.width(), bounds.height());
    226 }
    227 
    228 void CoreOobeHandler::SetClientAreaSize(int width, int height) {
    229   CallJS("setClientAreaSize", width, height);
    230 }
    231 
    232 void CoreOobeHandler::HandleInitialized() {
    233   oobe_ui_->InitializeHandlers();
    234 }
    235 
    236 void CoreOobeHandler::HandleSkipUpdateEnrollAfterEula() {
    237   WizardController* controller = WizardController::default_controller();
    238   DCHECK(controller);
    239   if (controller)
    240     controller->SkipUpdateEnrollAfterEula();
    241 }
    242 
    243 void CoreOobeHandler::HandleUpdateCurrentScreen(const std::string& screen) {
    244   if (delegate_)
    245     delegate_->OnCurrentScreenChanged(screen);
    246 }
    247 
    248 void CoreOobeHandler::HandleEnableHighContrast(bool enabled) {
    249   AccessibilityManager::Get()->EnableHighContrast(enabled);
    250 }
    251 
    252 void CoreOobeHandler::HandleEnableLargeCursor(bool enabled) {
    253   AccessibilityManager::Get()->EnableLargeCursor(enabled);
    254 }
    255 
    256 void CoreOobeHandler::HandleEnableVirtualKeyboard(bool enabled) {
    257   AccessibilityManager::Get()->EnableVirtualKeyboard(enabled);
    258 }
    259 
    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 
    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 
    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 
    287 void CoreOobeHandler::HandleScreenAssetsLoaded(
    288     const std::string& screen_async_load_id) {
    289   oobe_ui_->OnScreenAssetsLoaded(screen_async_load_id);
    290 }
    291 
    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 
    299 void CoreOobeHandler::HandleToggleResetScreen() { ShowDeviceResetScreen(); }
    300 
    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 
    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 
    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 
    341 void CoreOobeHandler::OnOSVersionLabelTextUpdated(
    342     const std::string& os_version_label_text) {
    343   UpdateLabel("version", os_version_label_text);
    344 }
    345 
    346 void CoreOobeHandler::OnEnterpriseInfoUpdated(
    347     const std::string& message_text) {
    348   CallJS("setEnterpriseInfo", message_text);
    349 }
    350 
    351 void CoreOobeHandler::UpdateLabel(const std::string& id,
    352                                   const std::string& text) {
    353   CallJS("setLabelText", id, text);
    354 }
    355 
    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 
    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 
    375 void CoreOobeHandler::UpdateClientAreaSize() {
    376   const gfx::Size& size = ash::Shell::GetScreen()->GetPrimaryDisplay().size();
    377   SetClientAreaSize(size.width(), size.height());
    378 }
    379 
    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 
    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 
    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 
    401 void CoreOobeHandler::InitDemoModeDetection() {
    402   demo_mode_detector_.InitDetection();
    403 }
    404 
    405 void CoreOobeHandler::StopDemoModeDetection() {
    406   demo_mode_detector_.StopDetection();
    407 }
    408 
    409 }  // namespace chromeos
    410