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