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