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/oobe_ui.h" 6 7 #include <string> 8 9 #include "ash/ash_switches.h" 10 #include "base/command_line.h" 11 #include "base/logging.h" 12 #include "base/memory/ref_counted_memory.h" 13 #include "base/values.h" 14 #include "chrome/browser/browser_about_handler.h" 15 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" 16 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h" 17 #include "chrome/browser/chromeos/login/login_display_host_impl.h" 18 #include "chrome/browser/chromeos/login/screen_locker.h" 19 #include "chrome/browser/chromeos/login/user_manager.h" 20 #include "chrome/browser/chromeos/login/wizard_controller.h" 21 #include "chrome/browser/chromeos/system/input_device_settings.h" 22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/ui/webui/about_ui.h" 24 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" 25 #include "chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h" 26 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h" 27 #include "chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h" 28 #include "chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.h" 29 #include "chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h" 30 #include "chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h" 31 #include "chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h" 32 #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h" 33 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" 34 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h" 35 #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h" 36 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" 37 #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h" 38 #include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h" 39 #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h" 40 #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h" 41 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h" 42 #include "chrome/browser/ui/webui/theme_source.h" 43 #include "chrome/common/chrome_constants.h" 44 #include "chrome/common/url_constants.h" 45 #include "chromeos/chromeos_constants.h" 46 #include "chromeos/chromeos_switches.h" 47 #include "content/public/browser/web_ui.h" 48 #include "content/public/browser/web_ui_data_source.h" 49 #include "grit/browser_resources.h" 50 #include "ui/base/resource/resource_bundle.h" 51 #include "ui/webui/web_ui_util.h" 52 53 namespace chromeos { 54 55 namespace { 56 57 // Path for a stripped down login page that does not have OOBE elements. 58 const char kLoginPath[] = "login#login"; 59 60 const char kStringsJSPath[] = "strings.js"; 61 const char kLoginJSPath[] = "login.js"; 62 const char kOobeJSPath[] = "oobe.js"; 63 const char kKeyboardUtilsJSPath[] = "keyboard_utils.js"; 64 const char kDemoUserLoginJSPath[] = "demo_user_login.js"; 65 66 // Paths for deferred resource loading. 67 const char kEnrollmentHTMLPath[] = "enrollment.html"; 68 const char kEnrollmentCSSPath[] = "enrollment.css"; 69 const char kEnrollmentJSPath[] = "enrollment.js"; 70 71 // Filter handler of chrome://oobe data source. 72 bool HandleRequestCallback( 73 const std::string& path, 74 const content::WebUIDataSource::GotDataCallback& callback) { 75 if (UserManager::Get()->IsUserLoggedIn() && 76 !UserManager::Get()->IsLoggedInAsStub() && 77 !ScreenLocker::default_screen_locker()) { 78 scoped_refptr<base::RefCountedBytes> empty_bytes = 79 new base::RefCountedBytes(); 80 callback.Run(empty_bytes.get()); 81 return true; 82 } 83 84 return false; 85 } 86 87 // Creates a WebUIDataSource for chrome://oobe 88 content::WebUIDataSource* CreateOobeUIDataSource( 89 const base::DictionaryValue& localized_strings) { 90 content::WebUIDataSource* source = 91 content::WebUIDataSource::Create(chrome::kChromeUIOobeHost); 92 source->SetUseJsonJSFormatV2(); 93 source->AddLocalizedStrings(localized_strings); 94 source->SetJsonPath(kStringsJSPath); 95 96 if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) { 97 source->SetDefaultResource(IDR_DEMO_USER_LOGIN_HTML); 98 source->AddResourcePath(kDemoUserLoginJSPath, 99 IDR_DEMO_USER_LOGIN_JS); 100 return source; 101 } 102 103 source->SetDefaultResource(IDR_OOBE_HTML); 104 source->AddResourcePath(kOobeJSPath, 105 IDR_OOBE_JS); 106 source->AddResourcePath(kLoginPath, 107 IDR_LOGIN_HTML); 108 source->AddResourcePath(kLoginJSPath, 109 IDR_LOGIN_JS); 110 source->AddResourcePath(kKeyboardUtilsJSPath, 111 IDR_KEYBOARD_UTILS_JS); 112 source->OverrideContentSecurityPolicyFrameSrc( 113 "frame-src chrome://terms/ " 114 "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/;"); 115 116 // Serve deferred resources. 117 source->AddResourcePath(kEnrollmentHTMLPath, 118 IDR_OOBE_ENROLLMENT_HTML); 119 source->AddResourcePath(kEnrollmentCSSPath, 120 IDR_OOBE_ENROLLMENT_CSS); 121 source->AddResourcePath(kEnrollmentJSPath, 122 IDR_OOBE_ENROLLMENT_JS); 123 124 return source; 125 } 126 127 } // namespace 128 129 // static 130 const char OobeUI::kScreenOobeNetwork[] = "connect"; 131 const char OobeUI::kScreenOobeEula[] = "eula"; 132 const char OobeUI::kScreenOobeUpdate[] = "update"; 133 const char OobeUI::kScreenOobeEnrollment[] = "oauth-enrollment"; 134 const char OobeUI::kScreenGaiaSignin[] = "gaia-signin"; 135 const char OobeUI::kScreenAccountPicker[] = "account-picker"; 136 const char OobeUI::kScreenKioskAutolaunch[] = "autolaunch"; 137 const char OobeUI::kScreenKioskEnable[] = "kiosk-enable"; 138 const char OobeUI::kScreenErrorMessage[] = "error-message"; 139 const char OobeUI::kScreenUserImagePicker[] = "user-image"; 140 const char OobeUI::kScreenTpmError[] = "tpm-error-message"; 141 const char OobeUI::kScreenPasswordChanged[] = "password-changed"; 142 const char OobeUI::kScreenManagedUserCreationFlow[] 143 = "managed-user-creation"; 144 const char OobeUI::kScreenTermsOfService[] = "terms-of-service"; 145 const char OobeUI::kScreenWrongHWID[] = "wrong-hwid"; 146 147 OobeUI::OobeUI(content::WebUI* web_ui) 148 : WebUIController(web_ui), 149 core_handler_(NULL), 150 network_dropdown_handler_(NULL), 151 update_screen_handler_(NULL), 152 network_screen_actor_(NULL), 153 eula_screen_actor_(NULL), 154 reset_screen_actor_(NULL), 155 autolaunch_screen_actor_(NULL), 156 kiosk_enable_screen_actor_(NULL), 157 wrong_hwid_screen_actor_(NULL), 158 locally_managed_user_creation_screen_actor_(NULL), 159 error_screen_handler_(NULL), 160 signin_screen_handler_(NULL), 161 terms_of_service_screen_actor_(NULL), 162 user_image_screen_actor_(NULL), 163 kiosk_app_menu_handler_(NULL), 164 current_screen_(SCREEN_UNKNOWN), 165 ready_(false) { 166 InitializeScreenMaps(); 167 168 network_state_informer_ = new NetworkStateInformer(); 169 network_state_informer_->Init(); 170 171 core_handler_ = new CoreOobeHandler(this); 172 AddScreenHandler(core_handler_); 173 core_handler_->SetDelegate(this); 174 175 network_dropdown_handler_ = new NetworkDropdownHandler(); 176 AddScreenHandler(network_dropdown_handler_); 177 178 update_screen_handler_ = new UpdateScreenHandler(); 179 AddScreenHandler(update_screen_handler_); 180 network_dropdown_handler_->AddObserver(update_screen_handler_); 181 182 NetworkScreenHandler* network_screen_handler = 183 new NetworkScreenHandler(core_handler_); 184 network_screen_actor_ = network_screen_handler; 185 AddScreenHandler(network_screen_handler); 186 187 EulaScreenHandler* eula_screen_handler = new EulaScreenHandler(core_handler_); 188 eula_screen_actor_ = eula_screen_handler; 189 AddScreenHandler(eula_screen_handler); 190 191 ResetScreenHandler* reset_screen_handler = new ResetScreenHandler(); 192 reset_screen_actor_ = reset_screen_handler; 193 AddScreenHandler(reset_screen_handler); 194 195 KioskAutolaunchScreenHandler* autolaunch_screen_handler = 196 new KioskAutolaunchScreenHandler(); 197 autolaunch_screen_actor_ = autolaunch_screen_handler; 198 AddScreenHandler(autolaunch_screen_handler); 199 200 KioskEnableScreenHandler* kiosk_enable_screen_handler = 201 new KioskEnableScreenHandler(); 202 kiosk_enable_screen_actor_ = kiosk_enable_screen_handler; 203 AddScreenHandler(kiosk_enable_screen_handler); 204 205 LocallyManagedUserCreationScreenHandler* 206 locally_managed_user_creation_screen_handler = 207 new LocallyManagedUserCreationScreenHandler(); 208 locally_managed_user_creation_screen_actor_ = 209 locally_managed_user_creation_screen_handler; 210 AddScreenHandler(locally_managed_user_creation_screen_handler); 211 212 WrongHWIDScreenHandler* wrong_hwid_screen_handler = 213 new WrongHWIDScreenHandler(); 214 wrong_hwid_screen_actor_ = wrong_hwid_screen_handler; 215 AddScreenHandler(wrong_hwid_screen_handler); 216 217 EnrollmentScreenHandler* enrollment_screen_handler = 218 new EnrollmentScreenHandler(); 219 enrollment_screen_actor_ = enrollment_screen_handler; 220 AddScreenHandler(enrollment_screen_handler); 221 222 TermsOfServiceScreenHandler* terms_of_service_screen_handler = 223 new TermsOfServiceScreenHandler; 224 terms_of_service_screen_actor_ = terms_of_service_screen_handler; 225 AddScreenHandler(terms_of_service_screen_handler); 226 227 UserImageScreenHandler* user_image_screen_handler = 228 new UserImageScreenHandler(); 229 user_image_screen_actor_ = user_image_screen_handler; 230 AddScreenHandler(user_image_screen_handler); 231 232 error_screen_handler_ = new ErrorScreenHandler(network_state_informer_); 233 AddScreenHandler(error_screen_handler_); 234 235 signin_screen_handler_ = new SigninScreenHandler(network_state_informer_, 236 error_screen_handler_, 237 core_handler_); 238 AddScreenHandler(signin_screen_handler_); 239 240 // Initialize KioskAppMenuHandler. Note that it is NOT a screen handler. 241 kiosk_app_menu_handler_ = new KioskAppMenuHandler; 242 web_ui->AddMessageHandler(kiosk_app_menu_handler_); 243 244 base::DictionaryValue localized_strings; 245 GetLocalizedStrings(&localized_strings); 246 247 Profile* profile = Profile::FromWebUI(web_ui); 248 // Set up the chrome://theme/ source, for Chrome logo. 249 ThemeSource* theme = new ThemeSource(profile); 250 content::URLDataSource::Add(profile, theme); 251 252 // Set up the chrome://terms/ data source, for EULA content. 253 AboutUIHTMLSource* about_source = 254 new AboutUIHTMLSource(chrome::kChromeUITermsHost, profile); 255 content::URLDataSource::Add(profile, about_source); 256 257 // Set up the chrome://oobe/ source. 258 content::WebUIDataSource::Add(profile, 259 CreateOobeUIDataSource(localized_strings)); 260 261 // Set up the chrome://userimage/ source. 262 options::UserImageSource* user_image_source = 263 new options::UserImageSource(); 264 content::URLDataSource::Add(profile, user_image_source); 265 } 266 267 OobeUI::~OobeUI() { 268 core_handler_->SetDelegate(NULL); 269 network_dropdown_handler_->RemoveObserver(update_screen_handler_); 270 } 271 272 void OobeUI::ShowScreen(WizardScreen* screen) { 273 screen->Show(); 274 } 275 276 void OobeUI::HideScreen(WizardScreen* screen) { 277 screen->Hide(); 278 } 279 280 UpdateScreenActor* OobeUI::GetUpdateScreenActor() { 281 return update_screen_handler_; 282 } 283 284 NetworkScreenActor* OobeUI::GetNetworkScreenActor() { 285 return network_screen_actor_; 286 } 287 288 EulaScreenActor* OobeUI::GetEulaScreenActor() { 289 return eula_screen_actor_; 290 } 291 292 EnrollmentScreenActor* OobeUI::GetEnrollmentScreenActor() { 293 return enrollment_screen_actor_; 294 } 295 296 ResetScreenActor* OobeUI::GetResetScreenActor() { 297 return reset_screen_actor_; 298 } 299 300 KioskAutolaunchScreenActor* OobeUI::GetKioskAutolaunchScreenActor() { 301 return autolaunch_screen_actor_; 302 } 303 304 KioskEnableScreenActor* OobeUI::GetKioskEnableScreenActor() { 305 return kiosk_enable_screen_actor_; 306 } 307 308 TermsOfServiceScreenActor* OobeUI::GetTermsOfServiceScreenActor() { 309 return terms_of_service_screen_actor_; 310 } 311 312 WrongHWIDScreenActor* OobeUI::GetWrongHWIDScreenActor() { 313 return wrong_hwid_screen_actor_; 314 } 315 316 UserImageScreenActor* OobeUI::GetUserImageScreenActor() { 317 return user_image_screen_actor_; 318 } 319 320 ErrorScreenActor* OobeUI::GetErrorScreenActor() { 321 return error_screen_handler_; 322 } 323 324 LocallyManagedUserCreationScreenHandler* 325 OobeUI::GetLocallyManagedUserCreationScreenActor() { 326 return locally_managed_user_creation_screen_actor_; 327 } 328 329 void OobeUI::GetLocalizedStrings(base::DictionaryValue* localized_strings) { 330 // Note, handlers_[0] is a GenericHandler used by the WebUI. 331 for (size_t i = 0; i < handlers_.size(); ++i) 332 handlers_[i]->GetLocalizedStrings(localized_strings); 333 webui::SetFontAndTextDirection(localized_strings); 334 kiosk_app_menu_handler_->GetLocalizedStrings(localized_strings); 335 336 #if defined(GOOGLE_CHROME_BUILD) 337 localized_strings->SetString("buildType", "chrome"); 338 #else 339 localized_strings->SetString("buildType", "chromium"); 340 #endif 341 342 if (CommandLine::ForCurrentProcess()-> 343 HasSwitch(ash::switches::kAshDisableNewLockAnimations)) 344 localized_strings->SetString("lockAnimationsType", "old"); 345 else 346 localized_strings->SetString("lockAnimationsType", "new"); 347 348 // If we're not doing boot animation then WebUI should trigger 349 // wallpaper load on boot. 350 if (CommandLine::ForCurrentProcess()->HasSwitch( 351 switches::kDisableBootAnimation)) { 352 localized_strings->SetString("bootIntoWallpaper", "on"); 353 } else { 354 localized_strings->SetString("bootIntoWallpaper", "off"); 355 } 356 357 bool keyboard_driven_oobe = 358 system::keyboard_settings::ForceKeyboardDrivenUINavigation(); 359 localized_strings->SetString("highlightStrength", 360 keyboard_driven_oobe ? "strong" : "normal"); 361 } 362 363 void OobeUI::InitializeScreenMaps() { 364 screen_names_.resize(SCREEN_UNKNOWN); 365 screen_names_[SCREEN_OOBE_NETWORK] = kScreenOobeNetwork; 366 screen_names_[SCREEN_OOBE_EULA] = kScreenOobeEula; 367 screen_names_[SCREEN_OOBE_UPDATE] = kScreenOobeUpdate; 368 screen_names_[SCREEN_OOBE_ENROLLMENT] = kScreenOobeEnrollment; 369 screen_names_[SCREEN_GAIA_SIGNIN] = kScreenGaiaSignin; 370 screen_names_[SCREEN_ACCOUNT_PICKER] = kScreenAccountPicker; 371 screen_names_[SCREEN_KIOSK_AUTOLAUNCH] = kScreenKioskAutolaunch; 372 screen_names_[SCREEN_KIOSK_ENABLE] = kScreenKioskEnable; 373 screen_names_[SCREEN_ERROR_MESSAGE] = kScreenErrorMessage; 374 screen_names_[SCREEN_USER_IMAGE_PICKER] = kScreenUserImagePicker; 375 screen_names_[SCREEN_TPM_ERROR] = kScreenTpmError; 376 screen_names_[SCREEN_PASSWORD_CHANGED] = kScreenPasswordChanged; 377 screen_names_[SCREEN_CREATE_MANAGED_USER_FLOW] = 378 kScreenManagedUserCreationFlow; 379 screen_names_[SCREEN_TERMS_OF_SERVICE] = kScreenTermsOfService; 380 screen_names_[SCREEN_WRONG_HWID] = kScreenWrongHWID; 381 382 screen_ids_.clear(); 383 for (size_t i = 0; i < screen_names_.size(); ++i) 384 screen_ids_[screen_names_[i]] = static_cast<Screen>(i); 385 } 386 387 void OobeUI::AddScreenHandler(BaseScreenHandler* handler) { 388 web_ui()->AddMessageHandler(handler); 389 handlers_.push_back(handler); 390 } 391 392 void OobeUI::InitializeHandlers() { 393 ready_ = true; 394 for (size_t i = 0; i < ready_callbacks_.size(); ++i) 395 ready_callbacks_[i].Run(); 396 ready_callbacks_.clear(); 397 398 for (size_t i = 0; i < handlers_.size(); ++i) 399 handlers_[i]->InitializeBase(); 400 } 401 402 bool OobeUI::IsJSReady(const base::Closure& display_is_ready_callback) { 403 if (!ready_) 404 ready_callbacks_.push_back(display_is_ready_callback); 405 return ready_; 406 } 407 408 void OobeUI::ShowOobeUI(bool show) { 409 core_handler_->ShowOobeUI(show); 410 } 411 412 void OobeUI::ShowRetailModeLoginSpinner() { 413 signin_screen_handler_->ShowRetailModeLoginSpinner(); 414 } 415 416 void OobeUI::ShowSigninScreen(SigninScreenHandlerDelegate* delegate, 417 NativeWindowDelegate* native_window_delegate) { 418 signin_screen_handler_->SetDelegate(delegate); 419 signin_screen_handler_->SetNativeWindowDelegate(native_window_delegate); 420 signin_screen_handler_->Show(core_handler_->show_oobe_ui()); 421 } 422 423 void OobeUI::ResetSigninScreenHandlerDelegate() { 424 signin_screen_handler_->SetDelegate(NULL); 425 signin_screen_handler_->SetNativeWindowDelegate(NULL); 426 } 427 428 const std::string& OobeUI::GetScreenName(Screen screen) const { 429 DCHECK(screen >= 0 && screen < SCREEN_UNKNOWN); 430 return screen_names_[static_cast<size_t>(screen)]; 431 } 432 433 void OobeUI::OnCurrentScreenChanged(const std::string& screen) { 434 if (screen_ids_.count(screen)) { 435 current_screen_ = screen_ids_[screen]; 436 } else { 437 NOTREACHED() << "Screen should be registered in InitializeScreenMaps()"; 438 current_screen_ = SCREEN_UNKNOWN; 439 } 440 } 441 442 } // namespace chromeos 443