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 "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.
     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 
     71 CoreOobeHandler::~CoreOobeHandler() {
     72 }
     73 
     74 void CoreOobeHandler::SetDelegate(Delegate* delegate) {
     75   delegate_ = delegate;
     76 }
     77 
     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 
    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 
    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 
    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 
    151 void CoreOobeHandler::ShowTpmError() {
    152   CallJS("showTpmError");
    153 }
    154 
    155 void CoreOobeHandler::ShowSignInUI(const std::string& email) {
    156   CallJS("showSigninUI", email);
    157 }
    158 
    159 void CoreOobeHandler::ResetSignInUI(bool force_online) {
    160   CallJS("resetSigninUI", force_online);
    161 }
    162 
    163 void CoreOobeHandler::ClearUserPodPassword() {
    164   CallJS("clearUserPodPassword");
    165 }
    166 
    167 void CoreOobeHandler::RefocusCurrentPod() {
    168   CallJS("refocusCurrentPod");
    169 }
    170 
    171 void CoreOobeHandler::OnLoginSuccess(const std::string& username) {
    172   CallJS("onLoginSuccess", username);
    173 }
    174 
    175 void CoreOobeHandler::ShowPasswordChangedScreen(bool show_password_error) {
    176   CallJS("showPasswordChangedScreen", show_password_error);
    177 }
    178 
    179 void CoreOobeHandler::SetUsageStats(bool checked) {
    180   CallJS("setUsageStats", checked);
    181 }
    182 
    183 void CoreOobeHandler::SetOemEulaUrl(const std::string& oem_eula_url) {
    184   CallJS("setOemEulaUrl", oem_eula_url);
    185 }
    186 
    187 void CoreOobeHandler::SetTpmPassword(const std::string& tpm_password) {
    188   CallJS("setTpmPassword", tpm_password);
    189 }
    190 
    191 void CoreOobeHandler::ClearErrors() {
    192   CallJS("clearErrors");
    193 }
    194 
    195 void CoreOobeHandler::ReloadContent(const base::DictionaryValue& dictionary) {
    196   CallJS("reloadContent", dictionary);
    197 }
    198 
    199 void CoreOobeHandler::HandleInitialized() {
    200   oobe_ui_->InitializeHandlers();
    201 }
    202 
    203 void CoreOobeHandler::HandleSkipUpdateEnrollAfterEula() {
    204   WizardController* controller = WizardController::default_controller();
    205   DCHECK(controller);
    206   if (controller)
    207     controller->SkipUpdateEnrollAfterEula();
    208 }
    209 
    210 void CoreOobeHandler::HandleUpdateCurrentScreen(const std::string& screen) {
    211   if (delegate_)
    212     delegate_->OnCurrentScreenChanged(screen);
    213 }
    214 
    215 void CoreOobeHandler::HandleEnableHighContrast(bool enabled) {
    216   AccessibilityManager::Get()->EnableHighContrast(enabled);
    217 }
    218 
    219 void CoreOobeHandler::HandleEnableLargeCursor(bool enabled) {
    220   AccessibilityManager::Get()->EnableLargeCursor(enabled);
    221 }
    222 
    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 
    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 
    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 
    250 void CoreOobeHandler::HandleScreenAssetsLoaded(
    251     const std::string& screen_async_load_id) {
    252   oobe_ui_->OnScreenAssetsLoaded(screen_async_load_id);
    253 }
    254 
    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 
    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 
    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 
    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 
    300 void CoreOobeHandler::OnOSVersionLabelTextUpdated(
    301     const std::string& os_version_label_text) {
    302   UpdateLabel("version", os_version_label_text);
    303 }
    304 
    305 void CoreOobeHandler::OnEnterpriseInfoUpdated(
    306     const std::string& message_text) {
    307   CallJS("setEnterpriseInfo", message_text);
    308 }
    309 
    310 void CoreOobeHandler::UpdateLabel(const std::string& id,
    311                                   const std::string& text) {
    312   CallJS("setLabelText", id, text);
    313 }
    314 
    315 void CoreOobeHandler::UpdateDeviceRequisition() {
    316   CallJS("updateDeviceRequisition",
    317          g_browser_process->browser_policy_connector()->
    318              GetDeviceCloudPolicyManager()->GetDeviceRequisition());
    319 }
    320 
    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