1// Copyright 2013 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/gaia_screen_handler.h" 6 7#include "base/bind.h" 8#include "base/logging.h" 9#include "base/metrics/histogram.h" 10#include "base/prefs/pref_service.h" 11#include "base/strings/utf_string_conversions.h" 12#include "base/values.h" 13#include "chrome/browser/browser_process.h" 14#include "chrome/browser/browser_shutdown.h" 15#include "chrome/browser/chromeos/input_method/input_method_util.h" 16#include "chrome/browser/chromeos/language_preferences.h" 17#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" 18#include "chrome/browser/chromeos/policy/consumer_management_service.h" 19#include "chrome/browser/chromeos/profiles/profile_helper.h" 20#include "chrome/browser/chromeos/settings/cros_settings.h" 21#include "chrome/browser/io_thread.h" 22#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" 23#include "chrome/browser/ui/webui/signin/inline_login_ui.h" 24#include "chrome/common/pref_names.h" 25#include "chrome/grit/generated_resources.h" 26#include "chromeos/chromeos_switches.h" 27#include "chromeos/ime/input_method_manager.h" 28#include "chromeos/settings/cros_settings_names.h" 29#include "components/user_manager/user_manager.h" 30#include "content/public/browser/browser_thread.h" 31#include "content/public/browser/render_frame_host.h" 32#include "google_apis/gaia/gaia_auth_util.h" 33#include "google_apis/gaia/gaia_switches.h" 34#include "google_apis/gaia/gaia_urls.h" 35#include "ui/base/l10n/l10n_util.h" 36 37using content::BrowserThread; 38 39namespace chromeos { 40 41namespace { 42 43const char kJsScreenPath[] = "login.GaiaSigninScreen"; 44const char kAuthIframeParentName[] = "signin-frame"; 45const char kAuthIframeParentOrigin[] = 46 "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/"; 47 48void UpdateAuthParams(base::DictionaryValue* params, 49 bool has_users, 50 bool is_enrolling_consumer_management) { 51 CrosSettings* cros_settings = CrosSettings::Get(); 52 bool allow_new_user = true; 53 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); 54 bool allow_guest = true; 55 cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest); 56 // Account creation depends on Guest sign-in (http://crosbug.com/24570). 57 params->SetBoolean("createAccount", allow_new_user && allow_guest); 58 params->SetBoolean("guestSignin", allow_guest); 59 60 // Allow supervised user creation only if: 61 // 1. Enterprise managed device > is allowed by policy. 62 // 2. Consumer device > owner exists. 63 // 3. New users are allowed by owner. 64 // 4. Supervised users are allowed by owner. 65 bool supervised_users_allowed = 66 user_manager::UserManager::Get()->AreSupervisedUsersAllowed(); 67 bool supervised_users_can_create = true; 68 int message_id = -1; 69 if (!has_users) { 70 supervised_users_can_create = false; 71 message_id = IDS_CREATE_SUPERVISED_USER_NO_MANAGER_TEXT; 72 } 73 if (!allow_new_user || !supervised_users_allowed) { 74 supervised_users_can_create = false; 75 message_id = IDS_CREATE_SUPERVISED_USER_CREATION_RESTRICTED_TEXT; 76 } 77 78 params->SetBoolean("supervisedUsersEnabled", supervised_users_allowed); 79 params->SetBoolean("supervisedUsersCanCreate", supervised_users_can_create); 80 if (!supervised_users_can_create) { 81 params->SetString("supervisedUsersRestrictionReason", 82 l10n_util::GetStringUTF16(message_id)); 83 } 84 85 // Now check whether we're in multi-profiles user adding scenario and 86 // disable GAIA right panel features if that's the case. 87 // For consumer management enrollment, we also hide all right panel components 88 // and show only an enrollment message. 89 if (UserAddingScreen::Get()->IsRunning() || 90 is_enrolling_consumer_management) { 91 params->SetBoolean("createAccount", false); 92 params->SetBoolean("guestSignin", false); 93 params->SetBoolean("supervisedUsersEnabled", false); 94 } 95} 96 97void RecordSAMLScrapingVerificationResultInHistogram(bool success) { 98 UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.Scraping.VerificationResult", success); 99} 100 101// The Task posted to PostTaskAndReply in StartClearingDnsCache on the IO 102// thread. 103void ClearDnsCache(IOThread* io_thread) { 104 DCHECK_CURRENTLY_ON(BrowserThread::IO); 105 if (browser_shutdown::IsTryingToQuit()) 106 return; 107 108 io_thread->ClearHostCache(); 109} 110 111void PushFrontIMIfNotExists(const std::string& input_method, 112 std::vector<std::string>* input_methods) { 113 if (input_method.empty()) 114 return; 115 116 if (std::find(input_methods->begin(), input_methods->end(), input_method) == 117 input_methods->end()) 118 input_methods->insert(input_methods->begin(), input_method); 119} 120 121} // namespace 122 123GaiaContext::GaiaContext() 124 : force_reload(false), 125 is_local(false), 126 password_changed(false), 127 show_users(false), 128 use_offline(false), 129 has_users(false) {} 130 131GaiaScreenHandler::GaiaScreenHandler( 132 CoreOobeActor* core_oobe_actor, 133 const scoped_refptr<NetworkStateInformer>& network_state_informer, 134 policy::ConsumerManagementService* consumer_management) 135 : BaseScreenHandler(kJsScreenPath), 136 frame_state_(FRAME_STATE_UNKNOWN), 137 frame_error_(net::OK), 138 network_state_informer_(network_state_informer), 139 consumer_management_(consumer_management), 140 core_oobe_actor_(core_oobe_actor), 141 dns_cleared_(false), 142 dns_clear_task_running_(false), 143 cookies_cleared_(false), 144 focus_stolen_(false), 145 gaia_silent_load_(false), 146 using_saml_api_(false), 147 is_enrolling_consumer_management_(false), 148 test_expects_complete_login_(false), 149 signin_screen_handler_(NULL), 150 weak_factory_(this) { 151 DCHECK(network_state_informer_.get()); 152} 153 154GaiaScreenHandler::~GaiaScreenHandler() { 155} 156 157void GaiaScreenHandler::LoadGaia(const GaiaContext& context) { 158 base::DictionaryValue params; 159 const bool is_enrolling_consumer_management = 160 context.is_enrolling_consumer_management; 161 162 params.SetBoolean("forceReload", context.force_reload); 163 params.SetBoolean("isLocal", context.is_local); 164 params.SetBoolean("passwordChanged", context.password_changed); 165 params.SetBoolean("isShowUsers", context.show_users); 166 params.SetBoolean("useOffline", context.use_offline); 167 params.SetString("email", context.email); 168 params.SetBoolean("isEnrollingConsumerManagement", 169 is_enrolling_consumer_management); 170 171 UpdateAuthParams(¶ms, 172 context.has_users, 173 is_enrolling_consumer_management); 174 175 if (!context.use_offline) { 176 const std::string app_locale = g_browser_process->GetApplicationLocale(); 177 if (!app_locale.empty()) 178 params.SetString("hl", app_locale); 179 } else { 180 base::DictionaryValue* localized_strings = new base::DictionaryValue(); 181 localized_strings->SetString( 182 "stringEmail", l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_EMAIL)); 183 localized_strings->SetString( 184 "stringPassword", 185 l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_PASSWORD)); 186 localized_strings->SetString( 187 "stringSignIn", l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_SIGNIN)); 188 localized_strings->SetString( 189 "stringEmptyEmail", 190 l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_EMPTY_EMAIL)); 191 localized_strings->SetString( 192 "stringEmptyPassword", 193 l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_EMPTY_PASSWORD)); 194 localized_strings->SetString( 195 "stringError", l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_ERROR)); 196 params.Set("localizedStrings", localized_strings); 197 } 198 199 CommandLine* command_line = CommandLine::ForCurrentProcess(); 200 201 const GURL gaia_url = 202 command_line->HasSwitch(::switches::kGaiaUrl) 203 ? GURL(command_line->GetSwitchValueASCII(::switches::kGaiaUrl)) 204 : GaiaUrls::GetInstance()->gaia_url(); 205 params.SetString("gaiaUrl", gaia_url.spec()); 206 207 if (command_line->HasSwitch(chromeos::switches::kEnableEmbeddedSignin)) 208 params.SetBoolean("useEmbedded", true); 209 210 frame_state_ = FRAME_STATE_LOADING; 211 CallJS("loadAuthExtension", params); 212} 213 214void GaiaScreenHandler::UpdateGaia(const GaiaContext& context) { 215 base::DictionaryValue params; 216 UpdateAuthParams(¶ms, context.has_users, 217 context.is_enrolling_consumer_management); 218 CallJS("updateAuthExtension", params); 219} 220 221void GaiaScreenHandler::ReloadGaia(bool force_reload) { 222 if (frame_state_ == FRAME_STATE_LOADING && !force_reload) { 223 VLOG(1) << "Skipping reloading of Gaia since gaia is loading."; 224 return; 225 } 226 NetworkStateInformer::State state = network_state_informer_->state(); 227 if (state != NetworkStateInformer::ONLINE) { 228 VLOG(1) << "Skipping reloading of Gaia since network state=" 229 << NetworkStateInformer::StatusString(state); 230 return; 231 } 232 VLOG(1) << "Reloading Gaia."; 233 frame_state_ = FRAME_STATE_LOADING; 234 CallJS("doReload"); 235} 236 237void GaiaScreenHandler::DeclareLocalizedValues( 238 LocalizedValuesBuilder* builder) { 239 builder->Add("signinScreenTitle", IDS_SIGNIN_SCREEN_TITLE); 240 builder->Add("signinScreenPasswordChanged", 241 IDS_SIGNIN_SCREEN_PASSWORD_CHANGED); 242 builder->Add("createAccount", IDS_CREATE_ACCOUNT_HTML); 243 builder->Add("guestSignin", IDS_BROWSE_WITHOUT_SIGNING_IN_HTML); 244 builder->Add("createSupervisedUser", 245 IDS_CREATE_SUPERVISED_USER_HTML); 246 builder->Add("createSupervisedUserFeatureName", 247 IDS_CREATE_SUPERVISED_USER_FEATURE_NAME); 248 builder->Add("consumerManagementEnrollmentSigninMessage", 249 IDS_LOGIN_CONSUMER_MANAGEMENT_ENROLLMENT); 250 251 // Strings used by the SAML fatal error dialog. 252 builder->Add("fatalErrorMessageNoEmail", IDS_LOGIN_FATAL_ERROR_NO_EMAIL); 253 builder->Add("fatalErrorMessageNoPassword", 254 IDS_LOGIN_FATAL_ERROR_NO_PASSWORD); 255 builder->Add("fatalErrorMessageVerificationFailed", 256 IDS_LOGIN_FATAL_ERROR_PASSWORD_VERIFICATION); 257 builder->Add("fatalErrorMessageInsecureURL", 258 IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL); 259 builder->Add("fatalErrorInstructions", IDS_LOGIN_FATAL_ERROR_INSTRUCTIONS); 260 builder->Add("fatalErrorDismissButton", IDS_OK); 261} 262 263void GaiaScreenHandler::Initialize() { 264} 265 266void GaiaScreenHandler::RegisterMessages() { 267 AddCallback("frameLoadingCompleted", 268 &GaiaScreenHandler::HandleFrameLoadingCompleted); 269 AddCallback("completeLogin", &GaiaScreenHandler::HandleCompleteLogin); 270 AddCallback("completeAuthentication", 271 &GaiaScreenHandler::HandleCompleteAuthentication); 272 AddCallback("usingSAMLAPI", &GaiaScreenHandler::HandleUsingSAMLAPI); 273 AddCallback("scrapedPasswordCount", 274 &GaiaScreenHandler::HandleScrapedPasswordCount); 275 AddCallback("scrapedPasswordVerificationFailed", 276 &GaiaScreenHandler::HandleScrapedPasswordVerificationFailed); 277 AddCallback("loginWebuiReady", &GaiaScreenHandler::HandleGaiaUIReady); 278} 279 280void GaiaScreenHandler::HandleFrameLoadingCompleted(int status) { 281 const net::Error frame_error = static_cast<net::Error>(-status); 282 if (frame_error == net::ERR_ABORTED) { 283 LOG(WARNING) << "Ignoring Gaia frame error: " << frame_error; 284 return; 285 } 286 frame_error_ = frame_error; 287 if (frame_error == net::OK) { 288 VLOG(1) << "Gaia is loaded"; 289 frame_state_ = FRAME_STATE_LOADED; 290 } else { 291 LOG(WARNING) << "Gaia frame error: " << frame_error_; 292 frame_state_ = FRAME_STATE_ERROR; 293 } 294 295 if (network_state_informer_->state() != NetworkStateInformer::ONLINE) 296 return; 297 if (frame_state_ == FRAME_STATE_LOADED) 298 UpdateState(ErrorScreenActor::ERROR_REASON_UPDATE); 299 else if (frame_state_ == FRAME_STATE_ERROR) 300 UpdateState(ErrorScreenActor::ERROR_REASON_FRAME_ERROR); 301} 302 303void GaiaScreenHandler::HandleCompleteAuthentication( 304 const std::string& email, 305 const std::string& password, 306 const std::string& auth_code) { 307 if (!Delegate()) 308 return; 309 Delegate()->SetDisplayEmail(gaia::SanitizeEmail(email)); 310 UserContext user_context(email); 311 user_context.SetKey(Key(password)); 312 user_context.SetAuthCode(auth_code); 313 Delegate()->CompleteLogin(user_context); 314} 315 316void GaiaScreenHandler::HandleCompleteLogin(const std::string& typed_email, 317 const std::string& password, 318 bool using_saml) { 319 if (!is_enrolling_consumer_management_) { 320 DoCompleteLogin(typed_email, password, using_saml); 321 return; 322 } 323 324 // Consumer management enrollment is in progress. 325 const std::string owner_email = 326 user_manager::UserManager::Get()->GetOwnerEmail(); 327 if (typed_email != owner_email) { 328 // Show Gaia sign-in screen again, since we only allow the owner to sign 329 // in. 330 populated_email_ = owner_email; 331 ShowGaia(is_enrolling_consumer_management_); 332 return; 333 } 334 335 CHECK(consumer_management_); 336 consumer_management_->SetOwner(owner_email, 337 base::Bind(&GaiaScreenHandler::OnSetOwnerDone, 338 weak_factory_.GetWeakPtr(), 339 typed_email, 340 password, 341 using_saml)); 342} 343 344void GaiaScreenHandler::HandleUsingSAMLAPI() { 345 SetSAMLPrincipalsAPIUsed(true); 346} 347 348void GaiaScreenHandler::HandleScrapedPasswordCount(int password_count) { 349 SetSAMLPrincipalsAPIUsed(false); 350 // Use a histogram that has 11 buckets, one for each of the values in [0, 9] 351 // and an overflow bucket at the end. 352 UMA_HISTOGRAM_ENUMERATION( 353 "ChromeOS.SAML.Scraping.PasswordCount", std::min(password_count, 10), 11); 354 if (password_count == 0) 355 HandleScrapedPasswordVerificationFailed(); 356} 357 358void GaiaScreenHandler::HandleScrapedPasswordVerificationFailed() { 359 RecordSAMLScrapingVerificationResultInHistogram(false); 360} 361 362void GaiaScreenHandler::HandleGaiaUIReady() { 363 if (focus_stolen_) { 364 // Set focus to the Gaia page. 365 // TODO(altimofeev): temporary solution, until focus parameters are 366 // implemented on the Gaia side. 367 // Do this only once. Any subsequent call would relod GAIA frame. 368 focus_stolen_ = false; 369 const char code[] = 370 "if (typeof gWindowOnLoad != 'undefined') gWindowOnLoad();"; 371 content::RenderFrameHost* frame = InlineLoginUI::GetAuthIframe( 372 web_ui()->GetWebContents(), 373 GURL(kAuthIframeParentOrigin), 374 kAuthIframeParentName); 375 frame->ExecuteJavaScript(base::ASCIIToUTF16(code)); 376 } 377 if (gaia_silent_load_) { 378 focus_stolen_ = true; 379 // Prevent focus stealing by the Gaia page. 380 // TODO(altimofeev): temporary solution, until focus parameters are 381 // implemented on the Gaia side. 382 const char code[] = 383 "var gWindowOnLoad = window.onload; " 384 "window.onload=function() {};"; 385 content::RenderFrameHost* frame = InlineLoginUI::GetAuthIframe( 386 web_ui()->GetWebContents(), 387 GURL(kAuthIframeParentOrigin), 388 kAuthIframeParentName); 389 frame->ExecuteJavaScript(base::ASCIIToUTF16(code)); 390 391 // As we could miss and window.onload could already be called, restore 392 // focus to current pod (see crbug/175243). 393 DCHECK(signin_screen_handler_); 394 signin_screen_handler_->RefocusCurrentPod(); 395 } 396 HandleFrameLoadingCompleted(0); 397 398 if (test_expects_complete_login_) 399 SubmitLoginFormForTest(); 400} 401 402void GaiaScreenHandler::OnSetOwnerDone(const std::string& typed_email, 403 const std::string& password, 404 bool using_saml, 405 bool success) { 406 CHECK(consumer_management_); 407 if (success) { 408 consumer_management_->SetEnrollmentStage( 409 policy::ConsumerManagementService::ENROLLMENT_STAGE_OWNER_STORED); 410 } else { 411 LOG(ERROR) << "Failed to write owner e-mail to boot lockbox."; 412 consumer_management_->SetEnrollmentStage( 413 policy::ConsumerManagementService:: 414 ENROLLMENT_STAGE_BOOT_LOCKBOX_FAILED); 415 // We should continue logging in the user, as there's not much we can do 416 // here. 417 } 418 DoCompleteLogin(typed_email, password, using_saml); 419} 420 421void GaiaScreenHandler::DoCompleteLogin(const std::string& typed_email, 422 const std::string& password, 423 bool using_saml) { 424 if (!Delegate()) 425 return; 426 427 if (using_saml && !using_saml_api_) 428 RecordSAMLScrapingVerificationResultInHistogram(true); 429 430 const std::string sanitized_email = gaia::SanitizeEmail(typed_email); 431 Delegate()->SetDisplayEmail(sanitized_email); 432 UserContext user_context(sanitized_email); 433 user_context.SetKey(Key(password)); 434 user_context.SetAuthFlow(using_saml 435 ? UserContext::AUTH_FLOW_GAIA_WITH_SAML 436 : UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML); 437 Delegate()->CompleteLogin(user_context); 438 439 if (test_expects_complete_login_) { 440 VLOG(2) << "Complete test login for " << typed_email 441 << ", requested=" << test_user_; 442 443 test_expects_complete_login_ = false; 444 test_user_.clear(); 445 test_pass_.clear(); 446 } 447} 448 449void GaiaScreenHandler::PopulateEmail(const std::string& user_id) { 450 populated_email_ = user_id; 451} 452 453void GaiaScreenHandler::PasswordChangedFor(const std::string& user_id) { 454 password_changed_for_.insert(user_id); 455} 456 457void GaiaScreenHandler::StartClearingDnsCache() { 458 if (dns_clear_task_running_ || !g_browser_process->io_thread()) 459 return; 460 461 dns_cleared_ = false; 462 BrowserThread::PostTaskAndReply( 463 BrowserThread::IO, 464 FROM_HERE, 465 base::Bind(&ClearDnsCache, g_browser_process->io_thread()), 466 base::Bind(&GaiaScreenHandler::OnDnsCleared, weak_factory_.GetWeakPtr())); 467 dns_clear_task_running_ = true; 468} 469 470void GaiaScreenHandler::OnDnsCleared() { 471 DCHECK_CURRENTLY_ON(BrowserThread::UI); 472 dns_clear_task_running_ = false; 473 dns_cleared_ = true; 474 ShowGaiaScreenIfReady(); 475} 476 477void GaiaScreenHandler::StartClearingCookies( 478 const base::Closure& on_clear_callback) { 479 cookies_cleared_ = false; 480 ProfileHelper* profile_helper = ProfileHelper::Get(); 481 LOG_ASSERT(Profile::FromWebUI(web_ui()) == 482 profile_helper->GetSigninProfile()); 483 profile_helper->ClearSigninProfile( 484 base::Bind(&GaiaScreenHandler::OnCookiesCleared, 485 weak_factory_.GetWeakPtr(), 486 on_clear_callback)); 487} 488 489void GaiaScreenHandler::OnCookiesCleared( 490 const base::Closure& on_clear_callback) { 491 DCHECK_CURRENTLY_ON(BrowserThread::UI); 492 cookies_cleared_ = true; 493 on_clear_callback.Run(); 494} 495 496void GaiaScreenHandler::ShowSigninScreenForCreds(const std::string& username, 497 const std::string& password) { 498 VLOG(2) << "ShowSigninScreenForCreds for user " << username 499 << ", frame_state=" << frame_state(); 500 501 test_user_ = username; 502 test_pass_ = password; 503 test_expects_complete_login_ = true; 504 505 // Submit login form for test if gaia is ready. If gaia is loading, login 506 // will be attempted in HandleLoginWebuiReady after gaia is ready. Otherwise, 507 // reload gaia then follow the loading case. 508 if (frame_state() == GaiaScreenHandler::FRAME_STATE_LOADED) { 509 SubmitLoginFormForTest(); 510 } else if (frame_state() != GaiaScreenHandler::FRAME_STATE_LOADING) { 511 DCHECK(signin_screen_handler_); 512 signin_screen_handler_->OnShowAddUser(); 513 } 514} 515 516void GaiaScreenHandler::SubmitLoginFormForTest() { 517 VLOG(2) << "Submit login form for test, user=" << test_user_; 518 519 std::string code; 520 code += "document.getElementById('Email').value = '" + test_user_ + "';"; 521 code += "document.getElementById('Passwd').value = '" + test_pass_ + "';"; 522 code += "document.getElementById('signIn').click();"; 523 524 content::RenderFrameHost* frame = InlineLoginUI::GetAuthIframe( 525 web_ui()->GetWebContents(), 526 GURL(kAuthIframeParentOrigin), 527 kAuthIframeParentName); 528 frame->ExecuteJavaScript(base::ASCIIToUTF16(code)); 529 530 // Test properties are cleared in HandleCompleteLogin because the form 531 // submission might fail and login will not be attempted after reloading 532 // if they are cleared here. 533} 534 535void GaiaScreenHandler::SetSAMLPrincipalsAPIUsed(bool api_used) { 536 using_saml_api_ = api_used; 537 UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.APIUsed", api_used); 538} 539 540void GaiaScreenHandler::ShowGaia(bool is_enrolling_consumer_management) { 541 is_enrolling_consumer_management_ = is_enrolling_consumer_management; 542 if (gaia_silent_load_ && populated_email_.empty()) { 543 dns_cleared_ = true; 544 cookies_cleared_ = true; 545 ShowGaiaScreenIfReady(); 546 } else { 547 StartClearingDnsCache(); 548 StartClearingCookies(base::Bind(&GaiaScreenHandler::ShowGaiaScreenIfReady, 549 weak_factory_.GetWeakPtr())); 550 } 551} 552 553void GaiaScreenHandler::ShowGaiaScreenIfReady() { 554 if (!dns_cleared_ || !cookies_cleared_ || !Delegate()) 555 return; 556 557 std::string active_network_path = network_state_informer_->network_path(); 558 if (gaia_silent_load_ && 559 (network_state_informer_->state() != NetworkStateInformer::ONLINE || 560 gaia_silent_load_network_ != active_network_path)) { 561 // Network has changed. Force Gaia reload. 562 gaia_silent_load_ = false; 563 // Gaia page will be realoded, so focus isn't stolen anymore. 564 focus_stolen_ = false; 565 } 566 567 // Note that LoadAuthExtension clears |populated_email_|. 568 if (populated_email_.empty()) 569 Delegate()->LoadSigninWallpaper(); 570 else 571 Delegate()->LoadWallpaper(populated_email_); 572 573 input_method::InputMethodManager* imm = 574 input_method::InputMethodManager::Get(); 575 576 scoped_refptr<input_method::InputMethodManager::State> gaia_ime_state = 577 imm->GetActiveIMEState()->Clone(); 578 imm->SetState(gaia_ime_state); 579 580 // Set Least Recently Used input method for the user. 581 if (!populated_email_.empty()) { 582 signin_screen_handler_->SetUserInputMethod(populated_email_, 583 gaia_ime_state.get()); 584 } else { 585 std::vector<std::string> input_methods = 586 imm->GetInputMethodUtil()->GetHardwareLoginInputMethodIds(); 587 const std::string owner_im = signin_screen_handler_->GetUserLRUInputMethod( 588 user_manager::UserManager::Get()->GetOwnerEmail()); 589 const std::string system_im = g_browser_process->local_state()->GetString( 590 language_prefs::kPreferredKeyboardLayout); 591 592 PushFrontIMIfNotExists(owner_im, &input_methods); 593 PushFrontIMIfNotExists(system_im, &input_methods); 594 595 gaia_ime_state->EnableLoginLayouts( 596 g_browser_process->GetApplicationLocale(), input_methods); 597 598 if (!system_im.empty()) { 599 gaia_ime_state->ChangeInputMethod(system_im, false /* show_message */); 600 } else if (!owner_im.empty()) { 601 gaia_ime_state->ChangeInputMethod(owner_im, false /* show_message */); 602 } 603 } 604 605 LoadAuthExtension(!gaia_silent_load_, false, false); 606 signin_screen_handler_->UpdateUIState( 607 SigninScreenHandler::UI_STATE_GAIA_SIGNIN, NULL); 608 609 if (gaia_silent_load_) { 610 // The variable is assigned to false because silently loaded Gaia page was 611 // used. 612 gaia_silent_load_ = false; 613 if (focus_stolen_) 614 HandleGaiaUIReady(); 615 } 616 signin_screen_handler_->UpdateState(ErrorScreenActor::ERROR_REASON_UPDATE); 617 618 PrefService* prefs = g_browser_process->local_state(); 619 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) { 620 if (core_oobe_actor_) 621 core_oobe_actor_->ShowDeviceResetScreen(); 622 } 623} 624 625void GaiaScreenHandler::MaybePreloadAuthExtension() { 626 VLOG(1) << "MaybePreloadAuthExtension() call."; 627 628 // If cookies clearing was initiated or |dns_clear_task_running_| then auth 629 // extension showing has already been initiated and preloading is senseless. 630 if (signin_screen_handler_->ShouldLoadGaia() && 631 !gaia_silent_load_ && 632 !cookies_cleared_ && 633 !dns_clear_task_running_ && 634 network_state_informer_->state() == NetworkStateInformer::ONLINE) { 635 gaia_silent_load_ = true; 636 gaia_silent_load_network_ = network_state_informer_->network_path(); 637 LoadAuthExtension(true, true, false); 638 } 639} 640 641void GaiaScreenHandler::LoadAuthExtension(bool force, 642 bool silent_load, 643 bool offline) { 644 GaiaContext context; 645 context.force_reload = force; 646 context.is_local = offline; 647 context.password_changed = !populated_email_.empty() && 648 password_changed_for_.count(populated_email_); 649 context.use_offline = offline; 650 context.email = populated_email_; 651 context.is_enrolling_consumer_management = is_enrolling_consumer_management_; 652 if (Delegate()) { 653 context.show_users = Delegate()->IsShowUsers(); 654 context.has_users = !Delegate()->GetUsers().empty(); 655 } 656 657 populated_email_.clear(); 658 659 LoadGaia(context); 660} 661 662void GaiaScreenHandler::UpdateState(ErrorScreenActor::ErrorReason reason) { 663 if (signin_screen_handler_) 664 signin_screen_handler_->UpdateState(reason); 665} 666 667SigninScreenHandlerDelegate* GaiaScreenHandler::Delegate() { 668 DCHECK(signin_screen_handler_); 669 return signin_screen_handler_->delegate_; 670} 671 672void GaiaScreenHandler::SetSigninScreenHandler(SigninScreenHandler* handler) { 673 signin_screen_handler_ = handler; 674} 675} // namespace chromeos 676