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