Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / chromeos / login / signin_screen_handler.cc
blob2b8b2fb0180a6de4f30c442d4e2d986d0c85d36c
1 // Copyright (c) 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.
5 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
7 #include <algorithm>
8 #include <vector>
10 #include "ash/shell.h"
11 #include "ash/system/chromeos/devicetype_utils.h"
12 #include "ash/wm/lock_state_controller.h"
13 #include "base/bind.h"
14 #include "base/location.h"
15 #include "base/logging.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_registry_simple.h"
18 #include "base/prefs/pref_service.h"
19 #include "base/prefs/scoped_user_pref_update.h"
20 #include "base/strings/string16.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/sys_info.h"
25 #include "base/trace_event/trace_event.h"
26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/browser_process_platform_part_chromeos.h"
28 #include "chrome/browser/browser_shutdown.h"
29 #include "chrome/browser/chrome_notification_types.h"
30 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
31 #include "chrome/browser/chromeos/input_method/input_method_util.h"
32 #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
33 #include "chrome/browser/chromeos/login/hwid_checker.h"
34 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
35 #include "chrome/browser/chromeos/login/reauth_stats.h"
36 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
37 #include "chrome/browser/chromeos/login/screens/network_error.h"
38 #include "chrome/browser/chromeos/login/startup_utils.h"
39 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
40 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
41 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
42 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
43 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
44 #include "chrome/browser/chromeos/login/wizard_controller.h"
45 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
46 #include "chrome/browser/chromeos/policy/consumer_management_service.h"
47 #include "chrome/browser/chromeos/policy/consumer_management_stage.h"
48 #include "chrome/browser/chromeos/policy/device_local_account.h"
49 #include "chrome/browser/chromeos/profiles/profile_helper.h"
50 #include "chrome/browser/chromeos/settings/cros_settings.h"
51 #include "chrome/browser/chromeos/system/system_clock.h"
52 #include "chrome/browser/io_thread.h"
53 #include "chrome/browser/profiles/profile.h"
54 #include "chrome/browser/profiles/profile_metrics.h"
55 #include "chrome/browser/signin/easy_unlock_service.h"
56 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
57 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
58 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
59 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
60 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
61 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
62 #include "chrome/common/pref_names.h"
63 #include "chrome/common/url_constants.h"
64 #include "chrome/grit/chromium_strings.h"
65 #include "chrome/grit/generated_resources.h"
66 #include "chromeos/dbus/dbus_thread_manager.h"
67 #include "chromeos/dbus/power_manager_client.h"
68 #include "chromeos/login/auth/key.h"
69 #include "chromeos/login/auth/user_context.h"
70 #include "chromeos/network/network_state.h"
71 #include "chromeos/network/network_state_handler.h"
72 #include "components/login/localized_values_builder.h"
73 #include "components/proximity_auth/screenlock_bridge.h"
74 #include "components/user_manager/user.h"
75 #include "components/user_manager/user_manager.h"
76 #include "components/user_manager/user_type.h"
77 #include "content/public/browser/render_frame_host.h"
78 #include "content/public/browser/web_contents.h"
79 #include "google_apis/gaia/gaia_auth_util.h"
80 #include "third_party/cros_system_api/dbus/service_constants.h"
81 #include "ui/base/ime/chromeos/ime_keyboard.h"
82 #include "ui/base/ime/chromeos/input_method_descriptor.h"
83 #include "ui/base/ime/chromeos/input_method_manager.h"
84 #include "ui/base/webui/web_ui_util.h"
86 namespace {
88 // Max number of users to show.
89 const size_t kMaxUsers = 18;
91 // Timeout to delay first notification about offline state for a
92 // current network.
93 const int kOfflineTimeoutSec = 5;
95 // Timeout used to prevent infinite connecting to a flaky network.
96 const int kConnectingTimeoutSec = 60;
98 // Type of the login screen UI that is currently presented to user.
99 const char kSourceGaiaSignin[] = "gaia-signin";
100 const char kSourceAccountPicker[] = "account-picker";
102 static bool Contains(const std::vector<std::string>& container,
103 const std::string& value) {
104 return std::find(container.begin(), container.end(), value) !=
105 container.end();
108 class CallOnReturn {
109 public:
110 explicit CallOnReturn(const base::Closure& callback)
111 : callback_(callback), call_scheduled_(false) {}
113 ~CallOnReturn() {
114 if (call_scheduled_ && !callback_.is_null())
115 callback_.Run();
118 void CancelScheduledCall() { call_scheduled_ = false; }
119 void ScheduleCall() { call_scheduled_ = true; }
121 private:
122 base::Closure callback_;
123 bool call_scheduled_;
125 DISALLOW_COPY_AND_ASSIGN(CallOnReturn);
128 } // namespace
130 namespace chromeos {
132 namespace {
134 bool IsOnline(NetworkStateInformer::State state,
135 NetworkError::ErrorReason reason) {
136 return state == NetworkStateInformer::ONLINE &&
137 reason != NetworkError::ERROR_REASON_PORTAL_DETECTED &&
138 reason != NetworkError::ERROR_REASON_LOADING_TIMEOUT;
141 bool IsBehindCaptivePortal(NetworkStateInformer::State state,
142 NetworkError::ErrorReason reason) {
143 return state == NetworkStateInformer::CAPTIVE_PORTAL ||
144 reason == NetworkError::ERROR_REASON_PORTAL_DETECTED;
147 bool IsProxyError(NetworkStateInformer::State state,
148 NetworkError::ErrorReason reason,
149 net::Error frame_error) {
150 return state == NetworkStateInformer::PROXY_AUTH_REQUIRED ||
151 reason == NetworkError::ERROR_REASON_PROXY_AUTH_CANCELLED ||
152 reason == NetworkError::ERROR_REASON_PROXY_CONNECTION_FAILED ||
153 (reason == NetworkError::ERROR_REASON_FRAME_ERROR &&
154 (frame_error == net::ERR_PROXY_CONNECTION_FAILED ||
155 frame_error == net::ERR_TUNNEL_CONNECTION_FAILED));
158 bool IsSigninScreen(const OobeUI::Screen screen) {
159 return screen == OobeUI::SCREEN_GAIA_SIGNIN ||
160 screen == OobeUI::SCREEN_ACCOUNT_PICKER;
163 bool IsSigninScreenError(NetworkError::ErrorState error_state) {
164 return error_state == NetworkError::ERROR_STATE_PORTAL ||
165 error_state == NetworkError::ERROR_STATE_OFFLINE ||
166 error_state == NetworkError::ERROR_STATE_PROXY ||
167 error_state == NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT;
170 // Returns network name by service path.
171 std::string GetNetworkName(const std::string& service_path) {
172 const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
173 GetNetworkState(service_path);
174 if (!network)
175 return std::string();
176 return network->name();
179 static bool SetUserInputMethodImpl(
180 const std::string& username,
181 const std::string& user_input_method,
182 input_method::InputMethodManager::State* ime_state) {
183 if (!chromeos::input_method::InputMethodManager::Get()->IsLoginKeyboard(
184 user_input_method)) {
185 LOG(WARNING) << "SetUserInputMethod('" << username
186 << "'): stored user LRU input method '" << user_input_method
187 << "' is no longer Full Latin Keyboard Language"
188 << " (entry dropped). Use hardware default instead.";
190 PrefService* const local_state = g_browser_process->local_state();
191 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
193 base::DictionaryValue* const users_lru_input_methods = updater.Get();
194 if (users_lru_input_methods != NULL) {
195 users_lru_input_methods->SetStringWithoutPathExpansion(username, "");
197 return false;
200 if (!Contains(ime_state->GetActiveInputMethodIds(), user_input_method)) {
201 if (!ime_state->EnableInputMethod(user_input_method)) {
202 DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username
203 << "'): user input method '" << user_input_method
204 << "' is not enabled and enabling failed (ignored!).";
207 ime_state->ChangeInputMethod(user_input_method, false /* show_message */);
209 return true;
212 } // namespace
214 // LoginScreenContext implementation ------------------------------------------
216 LoginScreenContext::LoginScreenContext() {
217 Init();
220 LoginScreenContext::LoginScreenContext(const base::ListValue* args) {
221 Init();
223 if (!args || args->GetSize() == 0)
224 return;
225 std::string email;
226 if (args->GetString(0, &email))
227 email_ = email;
230 void LoginScreenContext::Init() {
231 oobe_ui_ = false;
234 // SigninScreenHandler implementation ------------------------------------------
236 SigninScreenHandler::SigninScreenHandler(
237 const scoped_refptr<NetworkStateInformer>& network_state_informer,
238 NetworkErrorModel* network_error_model,
239 CoreOobeActor* core_oobe_actor,
240 GaiaScreenHandler* gaia_screen_handler)
241 : network_state_informer_(network_state_informer),
242 network_error_model_(network_error_model),
243 core_oobe_actor_(core_oobe_actor),
244 caps_lock_enabled_(chromeos::input_method::InputMethodManager::Get()
245 ->GetImeKeyboard()
246 ->CapsLockIsEnabled()),
247 gaia_screen_handler_(gaia_screen_handler),
248 histogram_helper_(new ErrorScreensHistogramHelper("Signin")),
249 weak_factory_(this) {
250 DCHECK(network_state_informer_.get());
251 DCHECK(network_error_model_);
252 DCHECK(core_oobe_actor_);
253 DCHECK(gaia_screen_handler_);
254 gaia_screen_handler_->SetSigninScreenHandler(this);
255 network_state_informer_->AddObserver(this);
257 registrar_.Add(this,
258 chrome::NOTIFICATION_AUTH_NEEDED,
259 content::NotificationService::AllSources());
260 registrar_.Add(this,
261 chrome::NOTIFICATION_AUTH_SUPPLIED,
262 content::NotificationService::AllSources());
263 registrar_.Add(this,
264 chrome::NOTIFICATION_AUTH_CANCELLED,
265 content::NotificationService::AllSources());
267 chromeos::input_method::ImeKeyboard* keyboard =
268 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
269 if (keyboard)
270 keyboard->AddObserver(this);
272 max_mode_delegate_.reset(new TouchViewControllerDelegate());
273 max_mode_delegate_->AddObserver(this);
275 policy::ConsumerManagementService* consumer_management =
276 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
277 GetConsumerManagementService();
278 is_enrolling_consumer_management_ =
279 consumer_management &&
280 consumer_management->GetStage().IsEnrollmentRequested();
283 SigninScreenHandler::~SigninScreenHandler() {
284 OobeUI* oobe_ui = GetOobeUI();
285 if (oobe_ui && oobe_ui_observer_added_)
286 oobe_ui->RemoveObserver(this);
287 chromeos::input_method::ImeKeyboard* keyboard =
288 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
289 if (keyboard)
290 keyboard->RemoveObserver(this);
291 weak_factory_.InvalidateWeakPtrs();
292 if (delegate_)
293 delegate_->SetWebUIHandler(NULL);
294 network_state_informer_->RemoveObserver(this);
295 if (max_mode_delegate_) {
296 max_mode_delegate_->RemoveObserver(this);
297 max_mode_delegate_.reset(NULL);
299 proximity_auth::ScreenlockBridge::Get()->SetLockHandler(NULL);
300 proximity_auth::ScreenlockBridge::Get()->SetFocusedUser("");
303 // static
304 std::string SigninScreenHandler::GetUserLRUInputMethod(
305 const std::string& username) {
306 PrefService* const local_state = g_browser_process->local_state();
307 const base::DictionaryValue* users_lru_input_methods =
308 local_state->GetDictionary(prefs::kUsersLRUInputMethod);
310 if (!users_lru_input_methods) {
311 DLOG(WARNING) << "GetUserLRUInputMethod('" << username
312 << "'): no kUsersLRUInputMethod";
313 return std::string();
316 std::string input_method;
318 if (!users_lru_input_methods->GetStringWithoutPathExpansion(username,
319 &input_method)) {
320 DVLOG(0) << "GetUserLRUInputMethod('" << username
321 << "'): no input method for this user";
322 return std::string();
325 return input_method;
328 // static
329 // Update keyboard layout to least recently used by the user.
330 void SigninScreenHandler::SetUserInputMethod(
331 const std::string& username,
332 input_method::InputMethodManager::State* ime_state) {
333 bool succeed = false;
335 const std::string input_method = GetUserLRUInputMethod(username);
337 if (!input_method.empty())
338 succeed = SetUserInputMethodImpl(username, input_method, ime_state);
340 // This is also a case when LRU layout is set only for a few local users,
341 // thus others need to be switched to default locale.
342 // Otherwise they will end up using another user's locale to log in.
343 if (!succeed) {
344 DVLOG(0) << "SetUserInputMethod('" << username
345 << "'): failed to set user layout. Switching to default.";
347 ime_state->SetInputMethodLoginDefault();
351 void SigninScreenHandler::DeclareLocalizedValues(
352 ::login::LocalizedValuesBuilder* builder) {
353 builder->Add("passwordHint", IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT);
354 builder->Add("signingIn", IDS_LOGIN_POD_SIGNING_IN);
355 builder->Add("podMenuButtonAccessibleName",
356 IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME);
357 builder->Add("podMenuRemoveItemAccessibleName",
358 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME);
359 builder->Add("passwordFieldAccessibleName",
360 IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME);
361 builder->Add("signedIn", IDS_SCREEN_LOCK_ACTIVE_USER);
362 builder->Add("launchAppButton", IDS_LAUNCH_APP_BUTTON);
363 builder->Add("restart", IDS_RESTART_BUTTON);
364 builder->Add("shutDown", IDS_SHUTDOWN_BUTTON);
365 builder->Add("addUser", IDS_ADD_USER_BUTTON);
366 builder->Add("browseAsGuest", IDS_GO_INCOGNITO_BUTTON);
367 builder->Add("moreOptions", IDS_MORE_OPTIONS_BUTTON);
368 builder->Add("addSupervisedUser",
369 IDS_CREATE_LEGACY_SUPERVISED_USER_MENU_LABEL);
370 builder->Add("cancel", IDS_CANCEL);
371 builder->Add("signOutUser", IDS_SCREEN_LOCK_SIGN_OUT);
372 builder->Add("offlineLogin", IDS_OFFLINE_LOGIN_HTML);
373 builder->Add("ownerUserPattern", IDS_LOGIN_POD_OWNER_USER);
374 builder->Add("removeUser", IDS_LOGIN_POD_REMOVE_USER);
375 builder->Add("errorTpmFailureTitle", IDS_LOGIN_ERROR_TPM_FAILURE_TITLE);
376 builder->Add("errorTpmFailureReboot", IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT);
377 builder->Add("errorTpmFailureRebootButton",
378 IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT_BUTTON);
380 policy::BrowserPolicyConnectorChromeOS* connector =
381 g_browser_process->platform_part()->browser_policy_connector_chromeos();
382 builder->Add("disabledAddUserTooltip",
383 connector->IsEnterpriseManaged()
384 ? IDS_DISABLED_ADD_USER_TOOLTIP_ENTERPRISE
385 : IDS_DISABLED_ADD_USER_TOOLTIP);
387 builder->Add("supervisedUserExpiredTokenWarning",
388 IDS_SUPERVISED_USER_EXPIRED_TOKEN_WARNING);
389 builder->Add("signinBannerText", IDS_LOGIN_USER_ADDING_BANNER);
391 // Multi-profiles related strings.
392 builder->Add("multiProfilesRestrictedPolicyTitle",
393 IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE);
394 builder->Add("multiProfilesNotAllowedPolicyMsg",
395 IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG);
396 builder->Add("multiProfilesPrimaryOnlyPolicyMsg",
397 IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG);
398 builder->Add("multiProfilesOwnerPrimaryOnlyMsg",
399 IDS_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG);
401 // Strings used by password changed dialog.
402 builder->Add("passwordChangedDesc", IDS_LOGIN_PASSWORD_CHANGED_DESC);
403 builder->AddF("passwordChangedMoreInfo",
404 IDS_LOGIN_PASSWORD_CHANGED_MORE_INFO,
405 IDS_SHORT_PRODUCT_OS_NAME);
407 builder->Add("oldPasswordHint", IDS_LOGIN_PASSWORD_CHANGED_OLD_PASSWORD_HINT);
408 builder->Add("oldPasswordIncorrect",
409 IDS_LOGIN_PASSWORD_CHANGED_INCORRECT_OLD_PASSWORD);
410 builder->Add("passwordChangedCantRemember",
411 IDS_LOGIN_PASSWORD_CHANGED_CANT_REMEMBER);
412 builder->Add("passwordChangedBackButton",
413 IDS_LOGIN_PASSWORD_CHANGED_BACK_BUTTON);
414 builder->Add("passwordChangedsOkButton", IDS_OK);
415 builder->Add("passwordChangedProceedAnyway",
416 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY);
417 builder->Add("proceedAnywayButton",
418 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY_BUTTON);
419 builder->Add("nextButtonText", IDS_NEWGAIA_OFFLINE_NEXT_BUTTON_TEXT);
420 builder->Add("forgotOldPasswordButtonText",
421 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_FORGOT_PASSWORD);
422 builder->AddF("passwordChangedTitle",
423 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_TITLE,
424 ash::GetChromeOSDeviceName());
425 builder->Add("passwordChangedProceedAnywayTitle",
426 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_PROCEED_ANYWAY);
427 builder->Add("passwordChangedTryAgain",
428 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_TRY_AGAIN);
429 builder->Add("publicAccountInfoFormat", IDS_LOGIN_PUBLIC_ACCOUNT_INFO_FORMAT);
430 builder->Add("publicAccountReminder",
431 IDS_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER);
432 builder->Add("publicSessionLanguageAndInput",
433 IDS_LOGIN_PUBLIC_SESSION_LANGUAGE_AND_INPUT);
434 builder->Add("publicAccountEnter", IDS_LOGIN_PUBLIC_ACCOUNT_ENTER);
435 builder->Add("publicAccountEnterAccessibleName",
436 IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME);
437 builder->Add("publicSessionSelectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
438 builder->Add("publicSessionSelectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
439 builder->Add("removeUserWarningText",
440 base::string16());
441 builder->AddF("removeLegacySupervisedUserWarningText",
442 IDS_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING,
443 base::UTF8ToUTF16(
444 chrome::kLegacySupervisedUserManagementDisplayURL));
445 builder->Add("removeUserWarningButtonTitle",
446 IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON);
448 if (StartupUtils::IsWebviewSigninEnabled()) {
449 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE_NEW_GAIA_FLOW);
450 builder->AddF("confirmPasswordTitle",
451 IDS_LOGIN_CONFIRM_PASSWORD_TITLE_NEW_GAIA_FLOW,
452 ash::GetChromeOSDeviceName());
453 builder->Add("confirmPasswordLabel",
454 IDS_LOGIN_CONFIRM_PASSWORD_LABEL_NEW_GAIA_FLOW);
455 } else {
456 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE);
457 builder->Add("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE);
458 builder->Add("confirmPasswordLabel", IDS_LOGIN_CONFIRM_PASSWORD_LABEL);
460 builder->Add("confirmPasswordConfirmButton",
461 IDS_LOGIN_CONFIRM_PASSWORD_CONFIRM_BUTTON);
462 builder->Add("confirmPasswordText", IDS_LOGIN_CONFIRM_PASSWORD_TEXT);
463 builder->Add("confirmPasswordErrorText",
464 IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT);
466 builder->Add("confirmPasswordIncorrectPassword",
467 IDS_LOGIN_CONFIRM_PASSWORD_INCORRECT_PASSWORD);
468 builder->Add("accountSetupCancelDialogTitle",
469 IDS_LOGIN_ACCOUNT_SETUP_CANCEL_DIALOG_TITLE);
470 builder->Add("accountSetupCancelDialogNo",
471 IDS_LOGIN_ACCOUNT_SETUP_CANCEL_DIALOG_NO);
472 builder->Add("accountSetupCancelDialogYes",
473 IDS_LOGIN_ACCOUNT_SETUP_CANCEL_DIALOG_YES);
475 builder->Add("fatalEnrollmentError",
476 IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR);
477 builder->Add("insecureURLEnrollmentError",
478 IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR);
481 void SigninScreenHandler::RegisterMessages() {
482 AddCallback("authenticateUser", &SigninScreenHandler::HandleAuthenticateUser);
483 AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito);
484 AddCallback("showSupervisedUserCreationScreen",
485 &SigninScreenHandler::HandleShowSupervisedUserCreationScreen);
486 AddCallback("launchPublicSession",
487 &SigninScreenHandler::HandleLaunchPublicSession);
488 AddRawCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin);
489 AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem);
490 AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser);
491 AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem);
492 AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper);
493 AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser);
494 AddCallback("toggleEnrollmentScreen",
495 &SigninScreenHandler::HandleToggleEnrollmentScreen);
496 AddCallback("toggleEnableDebuggingScreen",
497 &SigninScreenHandler::HandleToggleEnableDebuggingScreen);
498 AddCallback("toggleKioskEnableScreen",
499 &SigninScreenHandler::HandleToggleKioskEnableScreen);
500 AddCallback("createAccount", &SigninScreenHandler::HandleCreateAccount);
501 AddCallback("accountPickerReady",
502 &SigninScreenHandler::HandleAccountPickerReady);
503 AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady);
504 AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser);
505 AddCallback("openProxySettings",
506 &SigninScreenHandler::HandleOpenProxySettings);
507 AddCallback("loginVisible", &SigninScreenHandler::HandleLoginVisible);
508 AddCallback("cancelPasswordChangedFlow",
509 &SigninScreenHandler::HandleCancelPasswordChangedFlow);
510 AddCallback("cancelUserAdding", &SigninScreenHandler::HandleCancelUserAdding);
511 AddCallback("migrateUserData", &SigninScreenHandler::HandleMigrateUserData);
512 AddCallback("resyncUserData", &SigninScreenHandler::HandleResyncUserData);
513 AddCallback("loginUIStateChanged",
514 &SigninScreenHandler::HandleLoginUIStateChanged);
515 AddCallback("unlockOnLoginSuccess",
516 &SigninScreenHandler::HandleUnlockOnLoginSuccess);
517 AddCallback("showLoadingTimeoutError",
518 &SigninScreenHandler::HandleShowLoadingTimeoutError);
519 AddCallback("updateOfflineLogin",
520 &SigninScreenHandler::HandleUpdateOfflineLogin);
521 AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
522 AddCallback("getPublicSessionKeyboardLayouts",
523 &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
524 AddCallback("cancelConsumerManagementEnrollment",
525 &SigninScreenHandler::HandleCancelConsumerManagementEnrollment);
526 AddCallback("getTouchViewState",
527 &SigninScreenHandler::HandleGetTouchViewState);
528 AddCallback("logRemoveUserWarningShown",
529 &SigninScreenHandler::HandleLogRemoveUserWarningShown);
530 AddCallback("firstIncorrectPasswordAttempt",
531 &SigninScreenHandler::HandleFirstIncorrectPasswordAttempt);
532 AddCallback("maxIncorrectPasswordAttempts",
533 &SigninScreenHandler::HandleMaxIncorrectPasswordAttempts);
535 // This message is sent by the kiosk app menu, but is handled here
536 // so we can tell the delegate to launch the app.
537 AddCallback("launchKioskApp", &SigninScreenHandler::HandleLaunchKioskApp);
540 void SigninScreenHandler::Show(const LoginScreenContext& context) {
541 CHECK(delegate_);
543 // Just initialize internal fields from context and call ShowImpl().
544 oobe_ui_ = context.oobe_ui();
546 std::string email;
547 if (is_enrolling_consumer_management_) {
548 // We don't check if the value of the owner e-mail is trusted because it is
549 // only used to pre-fill the e-mail field in Gaia sign-in page and a cached
550 // value is sufficient.
551 CrosSettings::Get()->GetString(kDeviceOwner, &email);
552 } else {
553 email = context.email();
555 gaia_screen_handler_->PopulateEmail(email);
556 ShowImpl();
557 histogram_helper_->OnScreenShow();
560 void SigninScreenHandler::SetDelegate(SigninScreenHandlerDelegate* delegate) {
561 delegate_ = delegate;
562 if (delegate_)
563 delegate_->SetWebUIHandler(this);
566 void SigninScreenHandler::SetNativeWindowDelegate(
567 NativeWindowDelegate* native_window_delegate) {
568 native_window_delegate_ = native_window_delegate;
571 void SigninScreenHandler::OnNetworkReady() {
572 VLOG(1) << "OnNetworkReady() call.";
573 DCHECK(gaia_screen_handler_);
574 gaia_screen_handler_->MaybePreloadAuthExtension();
577 void SigninScreenHandler::UpdateState(NetworkError::ErrorReason reason) {
578 // ERROR_REASON_FRAME_ERROR is an explicit signal from GAIA frame so it shoud
579 // force network error UI update.
580 bool force_update = reason == NetworkError::ERROR_REASON_FRAME_ERROR;
581 UpdateStateInternal(reason, force_update);
584 void SigninScreenHandler::SetFocusPODCallbackForTesting(
585 base::Closure callback) {
586 test_focus_pod_callback_ = callback;
589 void SigninScreenHandler::ZeroOfflineTimeoutForTesting() {
590 zero_offline_timeout_for_test_ = true;
593 // SigninScreenHandler, private: -----------------------------------------------
595 void SigninScreenHandler::ShowImpl() {
596 if (!page_is_ready()) {
597 show_on_init_ = true;
598 return;
601 if (!ime_state_.get())
602 ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState();
604 if (!oobe_ui_observer_added_) {
605 oobe_ui_observer_added_ = true;
606 GetOobeUI()->AddObserver(this);
609 if (oobe_ui_ || is_enrolling_consumer_management_) {
610 // Shows new user sign-in for OOBE.
611 OnShowAddUser();
612 } else {
613 // Populates account picker. Animation is turned off for now until we
614 // figure out how to make it fast enough.
615 delegate_->HandleGetUsers();
617 // Reset Caps Lock state when login screen is shown.
618 input_method::InputMethodManager::Get()
619 ->GetImeKeyboard()
620 ->SetCapsLockEnabled(false);
622 base::DictionaryValue params;
623 params.SetBoolean("disableAddUser", AllWhitelistedUsersPresent());
624 UpdateUIState(UI_STATE_ACCOUNT_PICKER, &params);
628 void SigninScreenHandler::UpdateUIState(UIState ui_state,
629 base::DictionaryValue* params) {
630 switch (ui_state) {
631 case UI_STATE_GAIA_SIGNIN:
632 ui_state_ = UI_STATE_GAIA_SIGNIN;
633 ShowScreen(OobeUI::kScreenGaiaSignin, params);
634 break;
635 case UI_STATE_ACCOUNT_PICKER:
636 ui_state_ = UI_STATE_ACCOUNT_PICKER;
637 DCHECK(gaia_screen_handler_);
638 gaia_screen_handler_->CancelShowGaiaAsync();
639 ShowScreen(OobeUI::kScreenAccountPicker, params);
640 break;
641 default:
642 NOTREACHED();
643 break;
647 // TODO(antrim@): split this method into small parts.
648 // TODO(antrim@): move this logic to GaiaScreenHandler.
649 void SigninScreenHandler::UpdateStateInternal(NetworkError::ErrorReason reason,
650 bool force_update) {
651 // Do nothing once user has signed in or sign in is in progress.
652 // TODO(antrim): We will end up here when processing network state
653 // notification but no ShowSigninScreen() was called so delegate_ will be
654 // NULL. Network state processing logic does not belong here.
655 if (delegate_ &&
656 (delegate_->IsUserSigninCompleted() || delegate_->IsSigninInProgress())) {
657 return;
660 NetworkStateInformer::State state = network_state_informer_->state();
661 const std::string network_path = network_state_informer_->network_path();
662 const std::string network_name = GetNetworkName(network_path);
664 // Skip "update" notification about OFFLINE state from
665 // NetworkStateInformer if previous notification already was
666 // delayed.
667 if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) &&
668 !force_update && !update_state_closure_.IsCancelled()) {
669 return;
672 update_state_closure_.Cancel();
674 if ((state == NetworkStateInformer::OFFLINE && !force_update) ||
675 has_pending_auth_ui_) {
676 update_state_closure_.Reset(
677 base::Bind(&SigninScreenHandler::UpdateStateInternal,
678 weak_factory_.GetWeakPtr(),
679 reason,
680 true));
681 base::MessageLoop::current()->PostDelayedTask(
682 FROM_HERE,
683 update_state_closure_.callback(),
684 base::TimeDelta::FromSeconds(
685 zero_offline_timeout_for_test_ ? 0 : kOfflineTimeoutSec));
686 return;
689 // Don't show or hide error screen if we're in connecting state.
690 if (state == NetworkStateInformer::CONNECTING && !force_update) {
691 if (connecting_closure_.IsCancelled()) {
692 // First notification about CONNECTING state.
693 connecting_closure_.Reset(
694 base::Bind(&SigninScreenHandler::UpdateStateInternal,
695 weak_factory_.GetWeakPtr(),
696 reason,
697 true));
698 base::MessageLoop::current()->PostDelayedTask(
699 FROM_HERE,
700 connecting_closure_.callback(),
701 base::TimeDelta::FromSeconds(kConnectingTimeoutSec));
703 return;
705 connecting_closure_.Cancel();
707 const bool is_online = IsOnline(state, reason);
708 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
709 const bool is_gaia_loading_timeout =
710 (reason == NetworkError::ERROR_REASON_LOADING_TIMEOUT);
711 const bool is_gaia_error =
712 FrameError() != net::OK && FrameError() != net::ERR_NETWORK_CHANGED;
713 const bool is_gaia_signin = IsGaiaVisible() || IsGaiaHiddenByError();
714 const bool error_screen_should_overlay =
715 !offline_login_active_ && IsGaiaVisible();
716 const bool from_not_online_to_online_transition =
717 is_online && last_network_state_ != NetworkStateInformer::ONLINE;
718 last_network_state_ = state;
720 CallOnReturn reload_gaia(base::Bind(
721 &SigninScreenHandler::ReloadGaia, weak_factory_.GetWeakPtr(), true));
723 if (is_online || !is_behind_captive_portal)
724 network_error_model_->HideCaptivePortal();
726 // Hide offline message (if needed) and return if current screen is
727 // not a Gaia frame.
728 if (!is_gaia_signin) {
729 if (!IsSigninScreenHiddenByError())
730 HideOfflineMessage(state, reason);
731 return;
734 // Use the online login page if the user has not used the machine for awhile.
735 if (offline_login_active_)
736 gaia_screen_handler_->MonitorOfflineIdle(is_online);
738 // Reload frame if network state is changed from {!ONLINE} -> ONLINE state.
739 if (reason == NetworkError::ERROR_REASON_NETWORK_STATE_CHANGED &&
740 from_not_online_to_online_transition) {
741 // Schedules a immediate retry.
742 LOG(WARNING) << "Retry frame load since network has been changed.";
743 gaia_reload_reason_ = reason;
744 reload_gaia.ScheduleCall();
747 if (reason == NetworkError::ERROR_REASON_PROXY_CONFIG_CHANGED &&
748 error_screen_should_overlay) {
749 // Schedules a immediate retry.
750 LOG(WARNING) << "Retry frameload since proxy settings has been changed.";
751 gaia_reload_reason_ = reason;
752 reload_gaia.ScheduleCall();
755 if (reason == NetworkError::ERROR_REASON_FRAME_ERROR &&
756 reason != gaia_reload_reason_ &&
757 !IsProxyError(state, reason, FrameError())) {
758 LOG(WARNING) << "Retry frame load due to reason: "
759 << NetworkError::ErrorReasonString(reason);
760 gaia_reload_reason_ = reason;
761 reload_gaia.ScheduleCall();
764 if (is_gaia_loading_timeout) {
765 LOG(WARNING) << "Retry frame load due to loading timeout.";
766 LOG(ERROR) << "UpdateStateInternal reload 4";
767 reload_gaia.ScheduleCall();
770 if ((!is_online || is_gaia_loading_timeout || is_gaia_error) &&
771 !offline_login_active_) {
772 SetupAndShowOfflineMessage(state, reason);
773 } else {
774 HideOfflineMessage(state, reason);
776 // Cancel scheduled GAIA reload (if any) to prevent double reloads.
777 reload_gaia.CancelScheduledCall();
781 void SigninScreenHandler::SetupAndShowOfflineMessage(
782 NetworkStateInformer::State state,
783 NetworkError::ErrorReason reason) {
784 const std::string network_path = network_state_informer_->network_path();
785 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
786 const bool is_proxy_error = IsProxyError(state, reason, FrameError());
787 const bool is_gaia_loading_timeout =
788 (reason == NetworkError::ERROR_REASON_LOADING_TIMEOUT);
790 if (is_proxy_error) {
791 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PROXY,
792 std::string());
793 } else if (is_behind_captive_portal) {
794 // Do not bother a user with obsessive captive portal showing. This
795 // check makes captive portal being shown only once: either when error
796 // screen is shown for the first time or when switching from another
797 // error screen (offline, proxy).
798 if (IsGaiaVisible() || (network_error_model_->GetErrorState() !=
799 NetworkError::ERROR_STATE_PORTAL)) {
800 network_error_model_->FixCaptivePortal();
802 const std::string network_name = GetNetworkName(network_path);
803 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PORTAL,
804 network_name);
805 } else if (is_gaia_loading_timeout) {
806 network_error_model_->SetErrorState(
807 NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT, std::string());
808 } else {
809 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_OFFLINE,
810 std::string());
813 const bool guest_signin_allowed =
814 IsGuestSigninAllowed() &&
815 IsSigninScreenError(network_error_model_->GetErrorState());
816 network_error_model_->AllowGuestSignin(guest_signin_allowed);
818 const bool offline_login_allowed =
819 IsOfflineLoginAllowed() &&
820 IsSigninScreenError(network_error_model_->GetErrorState()) &&
821 network_error_model_->GetErrorState() !=
822 NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT;
823 network_error_model_->AllowOfflineLogin(offline_login_allowed);
825 if (GetCurrentScreen() != OobeUI::SCREEN_ERROR_MESSAGE) {
826 network_error_model_->SetUIState(NetworkError::UI_STATE_SIGNIN);
827 network_error_model_->SetParentScreen(OobeUI::SCREEN_GAIA_SIGNIN);
828 network_error_model_->Show();
829 histogram_helper_->OnErrorShow(network_error_model_->GetErrorState());
833 void SigninScreenHandler::HideOfflineMessage(NetworkStateInformer::State state,
834 NetworkError::ErrorReason reason) {
835 if (!IsSigninScreenHiddenByError())
836 return;
838 gaia_reload_reason_ = NetworkError::ERROR_REASON_NONE;
840 network_error_model_->Hide();
841 histogram_helper_->OnErrorHide();
843 // Forces a reload for Gaia screen on hiding error message.
844 if (IsGaiaVisible() || IsGaiaHiddenByError())
845 ReloadGaia(reason == NetworkError::ERROR_REASON_NETWORK_STATE_CHANGED);
848 void SigninScreenHandler::ReloadGaia(bool force_reload) {
849 gaia_screen_handler_->ReloadGaia(force_reload);
852 void SigninScreenHandler::Initialize() {
853 // If delegate_ is NULL here (e.g. WebUIScreenLocker has been destroyed),
854 // don't do anything, just return.
855 if (!delegate_)
856 return;
858 if (show_on_init_) {
859 show_on_init_ = false;
860 ShowImpl();
864 gfx::NativeWindow SigninScreenHandler::GetNativeWindow() {
865 if (native_window_delegate_)
866 return native_window_delegate_->GetNativeWindow();
867 return NULL;
870 void SigninScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
871 registry->RegisterDictionaryPref(prefs::kUsersLRUInputMethod);
874 void SigninScreenHandler::OnCurrentScreenChanged(OobeUI::Screen current_screen,
875 OobeUI::Screen new_screen) {
876 if (new_screen == OobeUI::SCREEN_ACCOUNT_PICKER) {
877 // Restore active IME state if returning to user pod row screen.
878 input_method::InputMethodManager::Get()->SetState(ime_state_);
882 void SigninScreenHandler::ClearAndEnablePassword() {
883 core_oobe_actor_->ResetSignInUI(false);
886 void SigninScreenHandler::ClearUserPodPassword() {
887 core_oobe_actor_->ClearUserPodPassword();
890 void SigninScreenHandler::RefocusCurrentPod() {
891 core_oobe_actor_->RefocusCurrentPod();
894 void SigninScreenHandler::OnUserRemoved(const std::string& username) {
895 CallJS("login.AccountPickerScreen.removeUser", username);
896 if (delegate_->GetUsers().empty())
897 OnShowAddUser();
900 void SigninScreenHandler::OnUserImageChanged(const user_manager::User& user) {
901 if (page_is_ready())
902 CallJS("login.AccountPickerScreen.updateUserImage", user.email());
905 void SigninScreenHandler::OnPreferencesChanged() {
906 // Make sure that one of the login UI is fully functional now, otherwise
907 // preferences update would be picked up next time it will be shown.
908 if (!webui_visible_) {
909 LOG(WARNING) << "Login UI is not active - postponed prefs change.";
910 preferences_changed_delayed_ = true;
911 return;
914 if (delegate_ && !delegate_->IsShowUsers()) {
915 HandleShowAddUser(NULL);
916 } else {
917 if (delegate_)
918 delegate_->HandleGetUsers();
919 UpdateUIState(UI_STATE_ACCOUNT_PICKER, NULL);
921 preferences_changed_delayed_ = false;
924 void SigninScreenHandler::ResetSigninScreenHandlerDelegate() {
925 SetDelegate(NULL);
928 void SigninScreenHandler::ShowError(int login_attempts,
929 const std::string& error_text,
930 const std::string& help_link_text,
931 HelpAppLauncher::HelpTopic help_topic_id) {
932 core_oobe_actor_->ShowSignInError(login_attempts, error_text, help_link_text,
933 help_topic_id);
936 void SigninScreenHandler::ShowErrorScreen(LoginDisplay::SigninError error_id) {
937 switch (error_id) {
938 case LoginDisplay::TPM_ERROR:
939 core_oobe_actor_->ShowTpmError();
940 break;
941 default:
942 NOTREACHED() << "Unknown sign in error";
943 break;
947 void SigninScreenHandler::ShowSigninUI(const std::string& email) {
948 core_oobe_actor_->ShowSignInUI(email);
951 void SigninScreenHandler::ShowPasswordChangedDialog(bool show_password_error,
952 const std::string& email) {
953 core_oobe_actor_->ShowPasswordChangedScreen(show_password_error, email);
956 void SigninScreenHandler::ShowSigninScreenForCreds(
957 const std::string& username,
958 const std::string& password) {
959 DCHECK(gaia_screen_handler_);
960 gaia_screen_handler_->ShowSigninScreenForCreds(username, password);
963 void SigninScreenHandler::ShowWhitelistCheckFailedError() {
964 DCHECK(gaia_screen_handler_);
965 gaia_screen_handler_->ShowWhitelistCheckFailedError();
968 void SigninScreenHandler::Observe(int type,
969 const content::NotificationSource& source,
970 const content::NotificationDetails& details) {
971 switch (type) {
972 case chrome::NOTIFICATION_AUTH_NEEDED: {
973 has_pending_auth_ui_ = true;
974 break;
976 case chrome::NOTIFICATION_AUTH_SUPPLIED:
977 has_pending_auth_ui_ = false;
978 // Reload auth extension as proxy credentials are supplied.
979 if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
980 ReloadGaia(true);
981 update_state_closure_.Cancel();
982 break;
983 case chrome::NOTIFICATION_AUTH_CANCELLED: {
984 // Don't reload auth extension if proxy auth dialog was cancelled.
985 has_pending_auth_ui_ = false;
986 update_state_closure_.Cancel();
987 break;
989 default:
990 NOTREACHED() << "Unexpected notification " << type;
994 void SigninScreenHandler::OnMaximizeModeStarted() {
995 CallJS("login.AccountPickerScreen.setTouchViewState", true);
998 void SigninScreenHandler::OnMaximizeModeEnded() {
999 CallJS("login.AccountPickerScreen.setTouchViewState", false);
1002 bool SigninScreenHandler::ShouldLoadGaia() const {
1003 // Fetching of the extension is not started before account picker page is
1004 // loaded because it can affect the loading speed.
1005 // Do not load the extension for the screen locker, see crosbug.com/25018.
1006 return !ScreenLocker::default_screen_locker() &&
1007 is_account_picker_showing_first_time_;
1010 void SigninScreenHandler::UserSettingsChanged() {
1011 DCHECK(gaia_screen_handler_);
1012 GaiaContext context;
1013 if (delegate_)
1014 context.has_users = !delegate_->GetUsers().empty();
1015 gaia_screen_handler_->UpdateGaia(context);
1016 UpdateAddButtonStatus();
1019 void SigninScreenHandler::UpdateAddButtonStatus() {
1020 CallJS("cr.ui.login.DisplayManager.updateAddUserButtonStatus",
1021 AllWhitelistedUsersPresent());
1024 void SigninScreenHandler::HandleAuthenticateUser(const std::string& username,
1025 const std::string& password) {
1026 if (!delegate_)
1027 return;
1028 UserContext user_context(gaia::SanitizeEmail(username));
1029 user_context.SetKey(Key(password));
1030 delegate_->Login(user_context, SigninSpecifics());
1033 void SigninScreenHandler::HandleLaunchIncognito() {
1034 UserContext context(user_manager::USER_TYPE_GUEST, std::string());
1035 if (delegate_)
1036 delegate_->Login(context, SigninSpecifics());
1039 void SigninScreenHandler::HandleShowSupervisedUserCreationScreen() {
1040 if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
1041 LOG(ERROR) << "Managed users not allowed.";
1042 return;
1044 LoginDisplayHostImpl::default_host()->
1045 StartWizard(WizardController::kSupervisedUserCreationScreenName);
1048 void SigninScreenHandler::HandleLaunchPublicSession(
1049 const std::string& user_id,
1050 const std::string& locale,
1051 const std::string& input_method) {
1052 if (!delegate_)
1053 return;
1055 UserContext context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user_id);
1056 context.SetPublicSessionLocale(locale),
1057 context.SetPublicSessionInputMethod(input_method);
1058 delegate_->Login(context, SigninSpecifics());
1061 void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) {
1062 if (!delegate_ || delegate_->IsShowUsers()) {
1063 NOTREACHED();
1064 return;
1066 std::string email;
1067 args->GetString(0, &email);
1069 gaia_screen_handler_->PopulateEmail(email);
1070 // Load auth extension. Parameters are: force reload, do not load extension in
1071 // background, use offline version.
1072 gaia_screen_handler_->LoadAuthExtension(true, false, true);
1073 UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL);
1076 void SigninScreenHandler::HandleShutdownSystem() {
1077 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
1080 void SigninScreenHandler::HandleLoadWallpaper(const std::string& email) {
1081 if (delegate_)
1082 delegate_->LoadWallpaper(email);
1085 void SigninScreenHandler::HandleRebootSystem() {
1086 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
1089 void SigninScreenHandler::HandleRemoveUser(const std::string& email) {
1090 if (!delegate_)
1091 return;
1092 delegate_->RemoveUser(email);
1093 UpdateAddButtonStatus();
1096 void SigninScreenHandler::HandleShowAddUser(const base::ListValue* args) {
1097 TRACE_EVENT_ASYNC_STEP_INTO0("ui",
1098 "ShowLoginWebUI",
1099 LoginDisplayHostImpl::kShowLoginWebUIid,
1100 "ShowAddUser");
1101 std::string email;
1102 // |args| can be null if it's OOBE.
1103 if (args)
1104 args->GetString(0, &email);
1105 gaia_screen_handler_->PopulateEmail(email);
1106 if (!email.empty())
1107 SendReauthReason(email);
1108 OnShowAddUser();
1111 void SigninScreenHandler::HandleToggleEnrollmentScreen() {
1112 if (delegate_)
1113 delegate_->ShowEnterpriseEnrollmentScreen();
1116 void SigninScreenHandler::HandleToggleEnableDebuggingScreen() {
1117 if (delegate_)
1118 delegate_->ShowEnableDebuggingScreen();
1121 void SigninScreenHandler::HandleToggleKioskEnableScreen() {
1122 policy::BrowserPolicyConnectorChromeOS* connector =
1123 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1124 if (delegate_ && !connector->IsEnterpriseManaged() &&
1125 LoginDisplayHostImpl::default_host()) {
1126 delegate_->ShowKioskEnableScreen();
1130 void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() {
1131 policy::BrowserPolicyConnectorChromeOS* connector =
1132 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1133 if (delegate_ && !connector->IsEnterpriseManaged())
1134 delegate_->ShowKioskAutolaunchScreen();
1137 void SigninScreenHandler::LoadUsers(const base::ListValue& users_list,
1138 bool showGuest) {
1139 CallJS("login.AccountPickerScreen.loadUsers",
1140 users_list,
1141 delegate_->IsShowGuest());
1144 void SigninScreenHandler::HandleAccountPickerReady() {
1145 VLOG(0) << "Login WebUI >> AccountPickerReady";
1147 if (delegate_ && !ScreenLocker::default_screen_locker() &&
1148 !chromeos::IsMachineHWIDCorrect() &&
1149 !oobe_ui_) {
1150 delegate_->ShowWrongHWIDScreen();
1151 return;
1154 PrefService* prefs = g_browser_process->local_state();
1155 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
1156 if (core_oobe_actor_)
1157 core_oobe_actor_->ShowDeviceResetScreen();
1159 return;
1160 } else if (prefs->GetBoolean(prefs::kDebuggingFeaturesRequested)) {
1161 if (core_oobe_actor_)
1162 core_oobe_actor_->ShowEnableDebuggingScreen();
1164 return;
1167 is_account_picker_showing_first_time_ = true;
1169 if (delegate_)
1170 delegate_->OnSigninScreenReady();
1173 void SigninScreenHandler::HandleWallpaperReady() {
1174 if (ScreenLocker::default_screen_locker()) {
1175 ScreenLocker::default_screen_locker()->delegate()->
1176 OnLockBackgroundDisplayed();
1180 void SigninScreenHandler::HandleSignOutUser() {
1181 if (delegate_)
1182 delegate_->Signout();
1185 void SigninScreenHandler::HandleCreateAccount() {
1186 if (delegate_)
1187 delegate_->CreateAccount();
1190 void SigninScreenHandler::HandleOpenProxySettings() {
1191 LoginDisplayHostImpl::default_host()->OpenProxySettings();
1194 void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
1195 VLOG(1) << "Login WebUI >> loginVisible, src: " << source << ", "
1196 << "webui_visible_: " << webui_visible_;
1197 if (!webui_visible_) {
1198 // There might be multiple messages from OOBE UI so send notifications after
1199 // the first one only.
1200 content::NotificationService::current()->Notify(
1201 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
1202 content::NotificationService::AllSources(),
1203 content::NotificationService::NoDetails());
1204 TRACE_EVENT_ASYNC_END0(
1205 "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid);
1207 webui_visible_ = true;
1208 if (preferences_changed_delayed_)
1209 OnPreferencesChanged();
1212 void SigninScreenHandler::HandleCancelPasswordChangedFlow(
1213 const std::string& user_id) {
1214 if (!user_id.empty())
1215 RecordReauthReason(user_id, ReauthReason::PASSWORD_UPDATE_SKIPPED);
1216 gaia_screen_handler_->StartClearingCookies(
1217 base::Bind(&SigninScreenHandler::CancelPasswordChangedFlowInternal,
1218 weak_factory_.GetWeakPtr()));
1221 void SigninScreenHandler::HandleCancelUserAdding() {
1222 if (delegate_)
1223 delegate_->CancelUserAdding();
1226 void SigninScreenHandler::HandleMigrateUserData(
1227 const std::string& old_password) {
1228 if (delegate_)
1229 delegate_->MigrateUserData(old_password);
1232 void SigninScreenHandler::HandleResyncUserData() {
1233 if (delegate_)
1234 delegate_->ResyncUserData();
1237 void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source,
1238 bool active) {
1239 VLOG(0) << "Login WebUI >> active: " << active << ", "
1240 << "source: " << source;
1242 if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() &&
1243 KioskAppManager::Get()->IsAutoLaunchRequested()) {
1244 VLOG(0) << "Showing auto-launch warning";
1245 // On slow devices, the wallpaper animation is not shown initially, so we
1246 // must explicitly load the wallpaper. This is also the case for the
1247 // account-picker and gaia-signin UI states.
1248 delegate_->LoadSigninWallpaper();
1249 HandleToggleKioskAutolaunchScreen();
1250 return;
1253 if (source == kSourceGaiaSignin) {
1254 ui_state_ = UI_STATE_GAIA_SIGNIN;
1255 } else if (source == kSourceAccountPicker) {
1256 ui_state_ = UI_STATE_ACCOUNT_PICKER;
1257 } else {
1258 NOTREACHED();
1259 return;
1263 void SigninScreenHandler::HandleUnlockOnLoginSuccess() {
1264 DCHECK(user_manager::UserManager::Get()->IsUserLoggedIn());
1265 if (ScreenLocker::default_screen_locker())
1266 ScreenLocker::default_screen_locker()->UnlockOnLoginSuccess();
1269 void SigninScreenHandler::HandleShowLoadingTimeoutError() {
1270 UpdateState(NetworkError::ERROR_REASON_LOADING_TIMEOUT);
1273 void SigninScreenHandler::HandleUpdateOfflineLogin(bool offline_login_active) {
1274 offline_login_active_ = offline_login_active;
1277 void SigninScreenHandler::HandleFocusPod(const std::string& user_id) {
1278 SetUserInputMethod(user_id, ime_state_.get());
1279 WallpaperManager::Get()->SetUserWallpaperDelayed(user_id);
1280 proximity_auth::ScreenlockBridge::Get()->SetFocusedUser(user_id);
1281 if (delegate_)
1282 delegate_->CheckUserStatus(user_id);
1283 if (!test_focus_pod_callback_.is_null())
1284 test_focus_pod_callback_.Run();
1286 bool use_24hour_clock = false;
1287 if (user_manager::UserManager::Get()->GetKnownUserBooleanPref(
1288 user_id, prefs::kUse24HourClock, &use_24hour_clock)) {
1289 g_browser_process->platform_part()
1290 ->GetSystemClock()
1291 ->SetLastFocusedPodHourClockType(use_24hour_clock ? base::k24HourClock
1292 : base::k12HourClock);
1296 void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
1297 const std::string& user_id,
1298 const std::string& locale) {
1299 GetKeyboardLayoutsForLocale(
1300 base::Bind(&SigninScreenHandler::SendPublicSessionKeyboardLayouts,
1301 weak_factory_.GetWeakPtr(),
1302 user_id,
1303 locale),
1304 locale);
1307 void SigninScreenHandler::SendPublicSessionKeyboardLayouts(
1308 const std::string& user_id,
1309 const std::string& locale,
1310 scoped_ptr<base::ListValue> keyboard_layouts) {
1311 CallJS("login.AccountPickerScreen.setPublicSessionKeyboardLayouts",
1312 user_id,
1313 locale,
1314 *keyboard_layouts);
1317 void SigninScreenHandler::HandleLaunchKioskApp(const std::string& app_id,
1318 bool diagnostic_mode) {
1319 UserContext context(user_manager::USER_TYPE_KIOSK_APP, app_id);
1320 SigninSpecifics specifics;
1321 specifics.kiosk_diagnostic_mode = diagnostic_mode;
1322 if (delegate_)
1323 delegate_->Login(context, specifics);
1326 void SigninScreenHandler::HandleCancelConsumerManagementEnrollment() {
1327 policy::ConsumerManagementService* consumer_management =
1328 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
1329 GetConsumerManagementService();
1330 CHECK(consumer_management);
1331 consumer_management->SetStage(
1332 policy::ConsumerManagementStage::EnrollmentCanceled());
1333 is_enrolling_consumer_management_ = false;
1334 ShowImpl();
1337 void SigninScreenHandler::HandleGetTouchViewState() {
1338 if (max_mode_delegate_) {
1339 CallJS("login.AccountPickerScreen.setTouchViewState",
1340 max_mode_delegate_->IsMaximizeModeEnabled());
1344 void SigninScreenHandler::HandleLogRemoveUserWarningShown() {
1345 ProfileMetrics::LogProfileDeleteUser(
1346 ProfileMetrics::DELETE_PROFILE_USER_MANAGER_SHOW_WARNING);
1349 void SigninScreenHandler::HandleFirstIncorrectPasswordAttempt(
1350 const std::string& email) {
1351 // TODO(ginkage): Fix this case once crbug.com/469987 is ready.
1353 if (user_manager::UserManager::Get()->FindUsingSAML(email))
1354 RecordReauthReason(email, ReauthReason::INCORRECT_SAML_PASSWORD_ENTERED);
1358 void SigninScreenHandler::HandleMaxIncorrectPasswordAttempts(
1359 const std::string& email) {
1360 RecordReauthReason(email, ReauthReason::INCORRECT_PASSWORD_ENTERED);
1363 bool SigninScreenHandler::AllWhitelistedUsersPresent() {
1364 CrosSettings* cros_settings = CrosSettings::Get();
1365 bool allow_new_user = false;
1366 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
1367 if (allow_new_user)
1368 return false;
1369 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1370 const user_manager::UserList& users = user_manager->GetUsers();
1371 if (!delegate_ || users.size() > kMaxUsers) {
1372 return false;
1374 const base::ListValue* whitelist = NULL;
1375 if (!cros_settings->GetList(kAccountsPrefUsers, &whitelist) || !whitelist)
1376 return false;
1377 for (size_t i = 0; i < whitelist->GetSize(); ++i) {
1378 std::string whitelisted_user;
1379 // NB: Wildcards in the whitelist are also detected as not present here.
1380 if (!whitelist->GetString(i, &whitelisted_user) ||
1381 !user_manager->IsKnownUser(whitelisted_user)) {
1382 return false;
1385 return true;
1388 void SigninScreenHandler::CancelPasswordChangedFlowInternal() {
1389 if (delegate_) {
1390 ShowImpl();
1391 delegate_->CancelPasswordChangedFlow();
1395 OobeUI* SigninScreenHandler::GetOobeUI() const {
1396 return static_cast<OobeUI*>(web_ui()->GetController());
1399 OobeUI::Screen SigninScreenHandler::GetCurrentScreen() const {
1400 OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
1401 OobeUI* oobe_ui = GetOobeUI();
1402 if (oobe_ui)
1403 screen = oobe_ui->current_screen();
1404 return screen;
1407 bool SigninScreenHandler::IsGaiaVisible() const {
1408 return IsSigninScreen(GetCurrentScreen()) &&
1409 ui_state_ == UI_STATE_GAIA_SIGNIN;
1412 bool SigninScreenHandler::IsGaiaHiddenByError() const {
1413 return IsSigninScreenHiddenByError() &&
1414 ui_state_ == UI_STATE_GAIA_SIGNIN;
1417 bool SigninScreenHandler::IsSigninScreenHiddenByError() const {
1418 return (GetCurrentScreen() == OobeUI::SCREEN_ERROR_MESSAGE) &&
1419 (IsSigninScreen(network_error_model_->GetParentScreen()));
1422 bool SigninScreenHandler::IsGuestSigninAllowed() const {
1423 CrosSettings* cros_settings = CrosSettings::Get();
1424 if (!cros_settings)
1425 return false;
1426 bool allow_guest;
1427 cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
1428 return allow_guest;
1431 bool SigninScreenHandler::IsOfflineLoginAllowed() const {
1432 CrosSettings* cros_settings = CrosSettings::Get();
1433 if (!cros_settings)
1434 return false;
1436 // Offline login is allowed only when user pods are hidden.
1437 bool show_pods;
1438 cros_settings->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_pods);
1439 return !show_pods;
1442 void SigninScreenHandler::OnShowAddUser() {
1443 is_account_picker_showing_first_time_ = false;
1444 DCHECK(gaia_screen_handler_);
1445 gaia_screen_handler_->ShowGaiaAsync(is_enrolling_consumer_management_);
1448 net::Error SigninScreenHandler::FrameError() const {
1449 DCHECK(gaia_screen_handler_);
1450 return gaia_screen_handler_->frame_error();
1453 void SigninScreenHandler::OnCapsLockChanged(bool enabled) {
1454 caps_lock_enabled_ = enabled;
1455 if (page_is_ready())
1456 CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_);
1459 } // namespace chromeos