Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / login / gaia_screen_handler.cc
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
37 using content::BrowserThread;
38
39 namespace chromeos {
40
41 namespace {
42
43 const char kJsScreenPath[] = "login.GaiaSigninScreen";
44 const char kAuthIframeParentName[] = "signin-frame";
45 const char kAuthIframeParentOrigin[] =
46     "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/";
47
48 void 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
97 void 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.
103 void ClearDnsCache(IOThread* io_thread) {
104   DCHECK_CURRENTLY_ON(BrowserThread::IO);
105   if (browser_shutdown::IsTryingToQuit())
106     return;
107
108   io_thread->ClearHostCache();
109 }
110
111 void 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
123 GaiaContext::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
131 GaiaScreenHandler::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
154 GaiaScreenHandler::~GaiaScreenHandler() {
155 }
156
157 void 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(&params,
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
214 void GaiaScreenHandler::UpdateGaia(const GaiaContext& context) {
215   base::DictionaryValue params;
216   UpdateAuthParams(&params, context.has_users,
217                    context.is_enrolling_consumer_management);
218   CallJS("updateAuthExtension", params);
219 }
220
221 void 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
237 void 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
263 void GaiaScreenHandler::Initialize() {
264 }
265
266 void 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
280 void 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
303 void 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
316 void 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
344 void GaiaScreenHandler::HandleUsingSAMLAPI() {
345   SetSAMLPrincipalsAPIUsed(true);
346 }
347
348 void 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
358 void GaiaScreenHandler::HandleScrapedPasswordVerificationFailed() {
359   RecordSAMLScrapingVerificationResultInHistogram(false);
360 }
361
362 void 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
402 void 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
421 void 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
449 void GaiaScreenHandler::PopulateEmail(const std::string& user_id) {
450   populated_email_ = user_id;
451 }
452
453 void GaiaScreenHandler::PasswordChangedFor(const std::string& user_id) {
454   password_changed_for_.insert(user_id);
455 }
456
457 void 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
470 void GaiaScreenHandler::OnDnsCleared() {
471   DCHECK_CURRENTLY_ON(BrowserThread::UI);
472   dns_clear_task_running_ = false;
473   dns_cleared_ = true;
474   ShowGaiaScreenIfReady();
475 }
476
477 void 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
489 void 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
496 void 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
516 void 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
535 void GaiaScreenHandler::SetSAMLPrincipalsAPIUsed(bool api_used) {
536   using_saml_api_ = api_used;
537   UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.APIUsed", api_used);
538 }
539
540 void 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
553 void 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
625 void 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
641 void 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
662 void GaiaScreenHandler::UpdateState(ErrorScreenActor::ErrorReason reason) {
663   if (signin_screen_handler_)
664     signin_screen_handler_->UpdateState(reason);
665 }
666
667 SigninScreenHandlerDelegate* GaiaScreenHandler::Delegate() {
668   DCHECK(signin_screen_handler_);
669   return signin_screen_handler_->delegate_;
670 }
671
672 void GaiaScreenHandler::SetSigninScreenHandler(SigninScreenHandler* handler) {
673   signin_screen_handler_ = handler;
674 }
675 }  // namespace chromeos