Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / webui / chromeos / login / signin_screen_handler.cc
blob657ae77fad13ea27a8cbf702ca7c14d007578fbb
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 "chromeos/network/portal_detector/network_portal_detector.h"
73 #include "components/login/localized_values_builder.h"
74 #include "components/proximity_auth/screenlock_bridge.h"
75 #include "components/user_manager/user.h"
76 #include "components/user_manager/user_manager.h"
77 #include "components/user_manager/user_type.h"
78 #include "content/public/browser/render_frame_host.h"
79 #include "content/public/browser/web_contents.h"
80 #include "google_apis/gaia/gaia_auth_util.h"
81 #include "third_party/cros_system_api/dbus/service_constants.h"
82 #include "ui/base/ime/chromeos/ime_keyboard.h"
83 #include "ui/base/ime/chromeos/input_method_descriptor.h"
84 #include "ui/base/ime/chromeos/input_method_manager.h"
85 #include "ui/base/webui/web_ui_util.h"
87 namespace {
89 // Max number of users to show.
90 const size_t kMaxUsers = 18;
92 // Timeout to delay first notification about offline state for a
93 // current network.
94 const int kOfflineTimeoutSec = 5;
96 // Timeout used to prevent infinite connecting to a flaky network.
97 const int kConnectingTimeoutSec = 60;
99 // Type of the login screen UI that is currently presented to user.
100 const char kSourceGaiaSignin[] = "gaia-signin";
101 const char kSourceAccountPicker[] = "account-picker";
103 static bool Contains(const std::vector<std::string>& container,
104 const std::string& value) {
105 return std::find(container.begin(), container.end(), value) !=
106 container.end();
109 class CallOnReturn {
110 public:
111 explicit CallOnReturn(const base::Closure& callback)
112 : callback_(callback), call_scheduled_(false) {}
114 ~CallOnReturn() {
115 if (call_scheduled_ && !callback_.is_null())
116 callback_.Run();
119 void CancelScheduledCall() { call_scheduled_ = false; }
120 void ScheduleCall() { call_scheduled_ = true; }
122 private:
123 base::Closure callback_;
124 bool call_scheduled_;
126 DISALLOW_COPY_AND_ASSIGN(CallOnReturn);
129 } // namespace
131 namespace chromeos {
133 namespace {
135 bool IsOnline(NetworkStateInformer::State state,
136 NetworkError::ErrorReason reason) {
137 return state == NetworkStateInformer::ONLINE &&
138 reason != NetworkError::ERROR_REASON_PORTAL_DETECTED &&
139 reason != NetworkError::ERROR_REASON_LOADING_TIMEOUT;
142 bool IsBehindCaptivePortal(NetworkStateInformer::State state,
143 NetworkError::ErrorReason reason) {
144 return state == NetworkStateInformer::CAPTIVE_PORTAL ||
145 reason == NetworkError::ERROR_REASON_PORTAL_DETECTED;
148 bool IsProxyError(NetworkStateInformer::State state,
149 NetworkError::ErrorReason reason,
150 net::Error frame_error) {
151 return state == NetworkStateInformer::PROXY_AUTH_REQUIRED ||
152 reason == NetworkError::ERROR_REASON_PROXY_AUTH_CANCELLED ||
153 reason == NetworkError::ERROR_REASON_PROXY_CONNECTION_FAILED ||
154 (reason == NetworkError::ERROR_REASON_FRAME_ERROR &&
155 (frame_error == net::ERR_PROXY_CONNECTION_FAILED ||
156 frame_error == net::ERR_TUNNEL_CONNECTION_FAILED));
159 bool IsSigninScreen(const OobeUI::Screen screen) {
160 return screen == OobeUI::SCREEN_GAIA_SIGNIN ||
161 screen == OobeUI::SCREEN_ACCOUNT_PICKER;
164 bool IsSigninScreenError(NetworkError::ErrorState error_state) {
165 return error_state == NetworkError::ERROR_STATE_PORTAL ||
166 error_state == NetworkError::ERROR_STATE_OFFLINE ||
167 error_state == NetworkError::ERROR_STATE_PROXY ||
168 error_state == NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT;
171 // Returns network name by service path.
172 std::string GetNetworkName(const std::string& service_path) {
173 const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
174 GetNetworkState(service_path);
175 if (!network)
176 return std::string();
177 return network->name();
180 static bool SetUserInputMethodImpl(
181 const std::string& username,
182 const std::string& user_input_method,
183 input_method::InputMethodManager::State* ime_state) {
184 if (!chromeos::input_method::InputMethodManager::Get()->IsLoginKeyboard(
185 user_input_method)) {
186 LOG(WARNING) << "SetUserInputMethod('" << username
187 << "'): stored user LRU input method '" << user_input_method
188 << "' is no longer Full Latin Keyboard Language"
189 << " (entry dropped). Use hardware default instead.";
191 PrefService* const local_state = g_browser_process->local_state();
192 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
194 base::DictionaryValue* const users_lru_input_methods = updater.Get();
195 if (users_lru_input_methods != NULL) {
196 users_lru_input_methods->SetStringWithoutPathExpansion(username, "");
198 return false;
201 if (!Contains(ime_state->GetActiveInputMethodIds(), user_input_method)) {
202 if (!ime_state->EnableInputMethod(user_input_method)) {
203 DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username
204 << "'): user input method '" << user_input_method
205 << "' is not enabled and enabling failed (ignored!).";
208 ime_state->ChangeInputMethod(user_input_method, false /* show_message */);
210 return true;
213 } // namespace
215 // LoginScreenContext implementation ------------------------------------------
217 LoginScreenContext::LoginScreenContext() {
218 Init();
221 LoginScreenContext::LoginScreenContext(const base::ListValue* args) {
222 Init();
224 if (!args || args->GetSize() == 0)
225 return;
226 std::string email;
227 if (args->GetString(0, &email))
228 email_ = email;
231 void LoginScreenContext::Init() {
232 oobe_ui_ = false;
235 // SigninScreenHandler implementation ------------------------------------------
237 SigninScreenHandler::SigninScreenHandler(
238 const scoped_refptr<NetworkStateInformer>& network_state_informer,
239 NetworkErrorModel* network_error_model,
240 CoreOobeActor* core_oobe_actor,
241 GaiaScreenHandler* gaia_screen_handler)
242 : network_state_informer_(network_state_informer),
243 network_error_model_(network_error_model),
244 core_oobe_actor_(core_oobe_actor),
245 caps_lock_enabled_(chromeos::input_method::InputMethodManager::Get()
246 ->GetImeKeyboard()
247 ->CapsLockIsEnabled()),
248 gaia_screen_handler_(gaia_screen_handler),
249 histogram_helper_(new ErrorScreensHistogramHelper("Signin")),
250 weak_factory_(this) {
251 DCHECK(network_state_informer_.get());
252 DCHECK(network_error_model_);
253 DCHECK(core_oobe_actor_);
254 DCHECK(gaia_screen_handler_);
255 gaia_screen_handler_->SetSigninScreenHandler(this);
256 network_state_informer_->AddObserver(this);
258 registrar_.Add(this,
259 chrome::NOTIFICATION_AUTH_NEEDED,
260 content::NotificationService::AllSources());
261 registrar_.Add(this,
262 chrome::NOTIFICATION_AUTH_SUPPLIED,
263 content::NotificationService::AllSources());
264 registrar_.Add(this,
265 chrome::NOTIFICATION_AUTH_CANCELLED,
266 content::NotificationService::AllSources());
268 chromeos::input_method::ImeKeyboard* keyboard =
269 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
270 if (keyboard)
271 keyboard->AddObserver(this);
273 max_mode_delegate_.reset(new TouchViewControllerDelegate());
274 max_mode_delegate_->AddObserver(this);
276 policy::ConsumerManagementService* consumer_management =
277 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
278 GetConsumerManagementService();
279 is_enrolling_consumer_management_ =
280 consumer_management &&
281 consumer_management->GetStage().IsEnrollmentRequested();
284 SigninScreenHandler::~SigninScreenHandler() {
285 OobeUI* oobe_ui = GetOobeUI();
286 if (oobe_ui && oobe_ui_observer_added_)
287 oobe_ui->RemoveObserver(this);
288 chromeos::input_method::ImeKeyboard* keyboard =
289 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
290 if (keyboard)
291 keyboard->RemoveObserver(this);
292 weak_factory_.InvalidateWeakPtrs();
293 if (delegate_)
294 delegate_->SetWebUIHandler(NULL);
295 network_state_informer_->RemoveObserver(this);
296 if (max_mode_delegate_) {
297 max_mode_delegate_->RemoveObserver(this);
298 max_mode_delegate_.reset(NULL);
300 proximity_auth::ScreenlockBridge::Get()->SetLockHandler(NULL);
301 proximity_auth::ScreenlockBridge::Get()->SetFocusedUser("");
304 // static
305 std::string SigninScreenHandler::GetUserLRUInputMethod(
306 const std::string& username) {
307 PrefService* const local_state = g_browser_process->local_state();
308 const base::DictionaryValue* users_lru_input_methods =
309 local_state->GetDictionary(prefs::kUsersLRUInputMethod);
311 if (!users_lru_input_methods) {
312 DLOG(WARNING) << "GetUserLRUInputMethod('" << username
313 << "'): no kUsersLRUInputMethod";
314 return std::string();
317 std::string input_method;
319 if (!users_lru_input_methods->GetStringWithoutPathExpansion(username,
320 &input_method)) {
321 DVLOG(0) << "GetUserLRUInputMethod('" << username
322 << "'): no input method for this user";
323 return std::string();
326 return input_method;
329 // static
330 // Update keyboard layout to least recently used by the user.
331 void SigninScreenHandler::SetUserInputMethod(
332 const std::string& username,
333 input_method::InputMethodManager::State* ime_state) {
334 bool succeed = false;
336 const std::string input_method = GetUserLRUInputMethod(username);
338 if (!input_method.empty())
339 succeed = SetUserInputMethodImpl(username, input_method, ime_state);
341 // This is also a case when LRU layout is set only for a few local users,
342 // thus others need to be switched to default locale.
343 // Otherwise they will end up using another user's locale to log in.
344 if (!succeed) {
345 DVLOG(0) << "SetUserInputMethod('" << username
346 << "'): failed to set user layout. Switching to default.";
348 ime_state->SetInputMethodLoginDefault();
352 void SigninScreenHandler::DeclareLocalizedValues(
353 ::login::LocalizedValuesBuilder* builder) {
354 builder->Add("passwordHint", IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT);
355 builder->Add("signingIn", IDS_LOGIN_POD_SIGNING_IN);
356 builder->Add("podMenuButtonAccessibleName",
357 IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME);
358 builder->Add("podMenuRemoveItemAccessibleName",
359 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME);
360 builder->Add("passwordFieldAccessibleName",
361 IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME);
362 builder->Add("signedIn", IDS_SCREEN_LOCK_ACTIVE_USER);
363 builder->Add("launchAppButton", IDS_LAUNCH_APP_BUTTON);
364 builder->Add("restart", IDS_RESTART_BUTTON);
365 builder->Add("shutDown", IDS_SHUTDOWN_BUTTON);
366 builder->Add("addUser", IDS_ADD_USER_BUTTON);
367 builder->Add("browseAsGuest", IDS_GO_INCOGNITO_BUTTON);
368 builder->Add("moreOptions", IDS_MORE_OPTIONS_BUTTON);
369 builder->Add("addSupervisedUser",
370 IDS_CREATE_LEGACY_SUPERVISED_USER_MENU_LABEL);
371 builder->Add("cancel", IDS_CANCEL);
372 builder->Add("signOutUser", IDS_SCREEN_LOCK_SIGN_OUT);
373 builder->Add("offlineLogin", IDS_OFFLINE_LOGIN_HTML);
374 builder->Add("ownerUserPattern", IDS_LOGIN_POD_OWNER_USER);
375 builder->Add("removeUser", IDS_LOGIN_POD_REMOVE_USER);
376 builder->Add("errorTpmFailureTitle", IDS_LOGIN_ERROR_TPM_FAILURE_TITLE);
377 builder->Add("errorTpmFailureReboot", IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT);
378 builder->Add("errorTpmFailureRebootButton",
379 IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT_BUTTON);
381 policy::BrowserPolicyConnectorChromeOS* connector =
382 g_browser_process->platform_part()->browser_policy_connector_chromeos();
383 builder->Add("disabledAddUserTooltip",
384 connector->IsEnterpriseManaged()
385 ? IDS_DISABLED_ADD_USER_TOOLTIP_ENTERPRISE
386 : IDS_DISABLED_ADD_USER_TOOLTIP);
388 builder->Add("supervisedUserExpiredTokenWarning",
389 IDS_SUPERVISED_USER_EXPIRED_TOKEN_WARNING);
390 builder->Add("signinBannerText", IDS_LOGIN_USER_ADDING_BANNER);
392 // Multi-profiles related strings.
393 builder->Add("multiProfilesRestrictedPolicyTitle",
394 IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE);
395 builder->Add("multiProfilesNotAllowedPolicyMsg",
396 IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG);
397 builder->Add("multiProfilesPrimaryOnlyPolicyMsg",
398 IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG);
399 builder->Add("multiProfilesOwnerPrimaryOnlyMsg",
400 IDS_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG);
402 // Strings used by password changed dialog.
403 builder->Add("passwordChangedDesc", IDS_LOGIN_PASSWORD_CHANGED_DESC);
404 builder->AddF("passwordChangedMoreInfo",
405 IDS_LOGIN_PASSWORD_CHANGED_MORE_INFO,
406 IDS_SHORT_PRODUCT_OS_NAME);
408 builder->Add("oldPasswordHint", IDS_LOGIN_PASSWORD_CHANGED_OLD_PASSWORD_HINT);
409 builder->Add("oldPasswordIncorrect",
410 IDS_LOGIN_PASSWORD_CHANGED_INCORRECT_OLD_PASSWORD);
411 builder->Add("passwordChangedCantRemember",
412 IDS_LOGIN_PASSWORD_CHANGED_CANT_REMEMBER);
413 builder->Add("passwordChangedBackButton",
414 IDS_LOGIN_PASSWORD_CHANGED_BACK_BUTTON);
415 builder->Add("passwordChangedsOkButton", IDS_OK);
416 builder->Add("passwordChangedProceedAnyway",
417 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY);
418 builder->Add("proceedAnywayButton",
419 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY_BUTTON);
420 builder->Add("nextButtonText", IDS_NEWGAIA_OFFLINE_NEXT_BUTTON_TEXT);
421 builder->Add("forgotOldPasswordButtonText",
422 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_FORGOT_PASSWORD);
423 builder->AddF("passwordChangedTitle",
424 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_TITLE,
425 ash::GetChromeOSDeviceName());
426 builder->Add("passwordChangedProceedAnywayTitle",
427 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_PROCEED_ANYWAY);
428 builder->Add("passwordChangedTryAgain",
429 IDS_LOGIN_NEWGAIA_PASSWORD_CHANGED_TRY_AGAIN);
430 builder->Add("publicAccountInfoFormat", IDS_LOGIN_PUBLIC_ACCOUNT_INFO_FORMAT);
431 builder->Add("publicAccountReminder",
432 IDS_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER);
433 builder->Add("publicSessionLanguageAndInput",
434 IDS_LOGIN_PUBLIC_SESSION_LANGUAGE_AND_INPUT);
435 builder->Add("publicAccountEnter", IDS_LOGIN_PUBLIC_ACCOUNT_ENTER);
436 builder->Add("publicAccountEnterAccessibleName",
437 IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME);
438 builder->Add("publicSessionSelectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
439 builder->Add("publicSessionSelectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
440 builder->Add("removeUserWarningText",
441 base::string16());
442 builder->AddF("removeLegacySupervisedUserWarningText",
443 IDS_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING,
444 base::UTF8ToUTF16(
445 chrome::kLegacySupervisedUserManagementDisplayURL));
446 builder->Add("removeUserWarningButtonTitle",
447 IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON);
449 if (StartupUtils::IsWebviewSigninEnabled()) {
450 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE_NEW_GAIA_FLOW);
451 builder->AddF("confirmPasswordTitle",
452 IDS_LOGIN_CONFIRM_PASSWORD_TITLE_NEW_GAIA_FLOW,
453 ash::GetChromeOSDeviceName());
454 builder->Add("confirmPasswordLabel",
455 IDS_LOGIN_CONFIRM_PASSWORD_LABEL_NEW_GAIA_FLOW);
456 } else {
457 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE);
458 builder->Add("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE);
459 builder->Add("confirmPasswordLabel", IDS_LOGIN_CONFIRM_PASSWORD_LABEL);
461 builder->Add("confirmPasswordConfirmButton",
462 IDS_LOGIN_CONFIRM_PASSWORD_CONFIRM_BUTTON);
463 builder->Add("confirmPasswordText", IDS_LOGIN_CONFIRM_PASSWORD_TEXT);
464 builder->Add("confirmPasswordErrorText",
465 IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT);
467 builder->Add("confirmPasswordIncorrectPassword",
468 IDS_LOGIN_CONFIRM_PASSWORD_INCORRECT_PASSWORD);
469 builder->Add("accountSetupCancelDialogTitle",
470 IDS_LOGIN_ACCOUNT_SETUP_CANCEL_DIALOG_TITLE);
471 builder->Add("accountSetupCancelDialogNo",
472 IDS_LOGIN_ACCOUNT_SETUP_CANCEL_DIALOG_NO);
473 builder->Add("accountSetupCancelDialogYes",
474 IDS_LOGIN_ACCOUNT_SETUP_CANCEL_DIALOG_YES);
476 builder->Add("fatalEnrollmentError",
477 IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR);
478 builder->Add("insecureURLEnrollmentError",
479 IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR);
482 void SigninScreenHandler::RegisterMessages() {
483 AddCallback("authenticateUser", &SigninScreenHandler::HandleAuthenticateUser);
484 AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito);
485 AddCallback("showSupervisedUserCreationScreen",
486 &SigninScreenHandler::HandleShowSupervisedUserCreationScreen);
487 AddCallback("launchPublicSession",
488 &SigninScreenHandler::HandleLaunchPublicSession);
489 AddRawCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin);
490 AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem);
491 AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser);
492 AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem);
493 AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper);
494 AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser);
495 AddCallback("toggleEnrollmentScreen",
496 &SigninScreenHandler::HandleToggleEnrollmentScreen);
497 AddCallback("toggleEnableDebuggingScreen",
498 &SigninScreenHandler::HandleToggleEnableDebuggingScreen);
499 AddCallback("toggleKioskEnableScreen",
500 &SigninScreenHandler::HandleToggleKioskEnableScreen);
501 AddCallback("createAccount", &SigninScreenHandler::HandleCreateAccount);
502 AddCallback("accountPickerReady",
503 &SigninScreenHandler::HandleAccountPickerReady);
504 AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady);
505 AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser);
506 AddCallback("openProxySettings",
507 &SigninScreenHandler::HandleOpenProxySettings);
508 AddCallback("loginVisible", &SigninScreenHandler::HandleLoginVisible);
509 AddCallback("cancelPasswordChangedFlow",
510 &SigninScreenHandler::HandleCancelPasswordChangedFlow);
511 AddCallback("cancelUserAdding", &SigninScreenHandler::HandleCancelUserAdding);
512 AddCallback("migrateUserData", &SigninScreenHandler::HandleMigrateUserData);
513 AddCallback("resyncUserData", &SigninScreenHandler::HandleResyncUserData);
514 AddCallback("loginUIStateChanged",
515 &SigninScreenHandler::HandleLoginUIStateChanged);
516 AddCallback("unlockOnLoginSuccess",
517 &SigninScreenHandler::HandleUnlockOnLoginSuccess);
518 AddCallback("showLoadingTimeoutError",
519 &SigninScreenHandler::HandleShowLoadingTimeoutError);
520 AddCallback("updateOfflineLogin",
521 &SigninScreenHandler::HandleUpdateOfflineLogin);
522 AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
523 AddCallback("getPublicSessionKeyboardLayouts",
524 &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
525 AddCallback("cancelConsumerManagementEnrollment",
526 &SigninScreenHandler::HandleCancelConsumerManagementEnrollment);
527 AddCallback("getTouchViewState",
528 &SigninScreenHandler::HandleGetTouchViewState);
529 AddCallback("logRemoveUserWarningShown",
530 &SigninScreenHandler::HandleLogRemoveUserWarningShown);
531 AddCallback("firstIncorrectPasswordAttempt",
532 &SigninScreenHandler::HandleFirstIncorrectPasswordAttempt);
533 AddCallback("maxIncorrectPasswordAttempts",
534 &SigninScreenHandler::HandleMaxIncorrectPasswordAttempts);
536 // This message is sent by the kiosk app menu, but is handled here
537 // so we can tell the delegate to launch the app.
538 AddCallback("launchKioskApp", &SigninScreenHandler::HandleLaunchKioskApp);
541 void SigninScreenHandler::Show(const LoginScreenContext& context) {
542 CHECK(delegate_);
544 // Just initialize internal fields from context and call ShowImpl().
545 oobe_ui_ = context.oobe_ui();
547 std::string email;
548 if (is_enrolling_consumer_management_) {
549 // We don't check if the value of the owner e-mail is trusted because it is
550 // only used to pre-fill the e-mail field in Gaia sign-in page and a cached
551 // value is sufficient.
552 CrosSettings::Get()->GetString(kDeviceOwner, &email);
553 } else {
554 email = context.email();
556 gaia_screen_handler_->PopulateEmail(email);
557 ShowImpl();
558 histogram_helper_->OnScreenShow();
561 void SigninScreenHandler::SetDelegate(SigninScreenHandlerDelegate* delegate) {
562 delegate_ = delegate;
563 if (delegate_)
564 delegate_->SetWebUIHandler(this);
567 void SigninScreenHandler::SetNativeWindowDelegate(
568 NativeWindowDelegate* native_window_delegate) {
569 native_window_delegate_ = native_window_delegate;
572 void SigninScreenHandler::OnNetworkReady() {
573 VLOG(1) << "OnNetworkReady() call.";
574 DCHECK(gaia_screen_handler_);
575 gaia_screen_handler_->MaybePreloadAuthExtension();
578 void SigninScreenHandler::UpdateState(NetworkError::ErrorReason reason) {
579 // ERROR_REASON_FRAME_ERROR is an explicit signal from GAIA frame so it shoud
580 // force network error UI update.
581 bool force_update = reason == NetworkError::ERROR_REASON_FRAME_ERROR;
582 UpdateStateInternal(reason, force_update);
585 void SigninScreenHandler::SetFocusPODCallbackForTesting(
586 base::Closure callback) {
587 test_focus_pod_callback_ = callback;
590 void SigninScreenHandler::ZeroOfflineTimeoutForTesting() {
591 zero_offline_timeout_for_test_ = true;
594 // SigninScreenHandler, private: -----------------------------------------------
596 void SigninScreenHandler::ShowImpl() {
597 if (!page_is_ready()) {
598 show_on_init_ = true;
599 return;
602 if (!ime_state_.get())
603 ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState();
605 if (!oobe_ui_observer_added_) {
606 oobe_ui_observer_added_ = true;
607 GetOobeUI()->AddObserver(this);
610 if (oobe_ui_ || is_enrolling_consumer_management_) {
611 // Shows new user sign-in for OOBE.
612 OnShowAddUser();
613 } else {
614 // Populates account picker. Animation is turned off for now until we
615 // figure out how to make it fast enough.
616 delegate_->HandleGetUsers();
618 // Reset Caps Lock state when login screen is shown.
619 input_method::InputMethodManager::Get()
620 ->GetImeKeyboard()
621 ->SetCapsLockEnabled(false);
623 base::DictionaryValue params;
624 params.SetBoolean("disableAddUser", AllWhitelistedUsersPresent());
625 UpdateUIState(UI_STATE_ACCOUNT_PICKER, &params);
629 void SigninScreenHandler::UpdateUIState(UIState ui_state,
630 base::DictionaryValue* params) {
631 switch (ui_state) {
632 case UI_STATE_GAIA_SIGNIN:
633 ui_state_ = UI_STATE_GAIA_SIGNIN;
634 ShowScreen(OobeUI::kScreenGaiaSignin, params);
635 break;
636 case UI_STATE_ACCOUNT_PICKER:
637 ui_state_ = UI_STATE_ACCOUNT_PICKER;
638 DCHECK(gaia_screen_handler_);
639 gaia_screen_handler_->CancelShowGaiaAsync();
640 ShowScreen(OobeUI::kScreenAccountPicker, params);
641 break;
642 default:
643 NOTREACHED();
644 break;
648 // TODO(antrim@): split this method into small parts.
649 // TODO(antrim@): move this logic to GaiaScreenHandler.
650 void SigninScreenHandler::UpdateStateInternal(NetworkError::ErrorReason reason,
651 bool force_update) {
652 // Do nothing once user has signed in or sign in is in progress.
653 // TODO(antrim): We will end up here when processing network state
654 // notification but no ShowSigninScreen() was called so delegate_ will be
655 // NULL. Network state processing logic does not belong here.
656 if (delegate_ &&
657 (delegate_->IsUserSigninCompleted() || delegate_->IsSigninInProgress())) {
658 return;
661 NetworkStateInformer::State state = network_state_informer_->state();
662 const std::string network_path = network_state_informer_->network_path();
663 const std::string network_name = GetNetworkName(network_path);
665 // Skip "update" notification about OFFLINE state from
666 // NetworkStateInformer if previous notification already was
667 // delayed.
668 if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) &&
669 !force_update && !update_state_closure_.IsCancelled()) {
670 return;
673 update_state_closure_.Cancel();
675 if ((state == NetworkStateInformer::OFFLINE && !force_update) ||
676 has_pending_auth_ui_) {
677 update_state_closure_.Reset(
678 base::Bind(&SigninScreenHandler::UpdateStateInternal,
679 weak_factory_.GetWeakPtr(),
680 reason,
681 true));
682 base::MessageLoop::current()->PostDelayedTask(
683 FROM_HERE,
684 update_state_closure_.callback(),
685 base::TimeDelta::FromSeconds(
686 zero_offline_timeout_for_test_ ? 0 : kOfflineTimeoutSec));
687 return;
690 // Don't show or hide error screen if we're in connecting state.
691 if (state == NetworkStateInformer::CONNECTING && !force_update) {
692 if (connecting_closure_.IsCancelled()) {
693 // First notification about CONNECTING state.
694 connecting_closure_.Reset(
695 base::Bind(&SigninScreenHandler::UpdateStateInternal,
696 weak_factory_.GetWeakPtr(),
697 reason,
698 true));
699 base::MessageLoop::current()->PostDelayedTask(
700 FROM_HERE,
701 connecting_closure_.callback(),
702 base::TimeDelta::FromSeconds(kConnectingTimeoutSec));
704 return;
706 connecting_closure_.Cancel();
708 const bool is_online = IsOnline(state, reason);
709 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
710 const bool is_gaia_loading_timeout =
711 (reason == NetworkError::ERROR_REASON_LOADING_TIMEOUT);
712 const bool is_gaia_error =
713 FrameError() != net::OK && FrameError() != net::ERR_NETWORK_CHANGED;
714 const bool is_gaia_signin = IsGaiaVisible() || IsGaiaHiddenByError();
715 const bool error_screen_should_overlay =
716 !offline_login_active_ && IsGaiaVisible();
717 const bool from_not_online_to_online_transition =
718 is_online && last_network_state_ != NetworkStateInformer::ONLINE;
719 last_network_state_ = state;
721 CallOnReturn reload_gaia(base::Bind(
722 &SigninScreenHandler::ReloadGaia, weak_factory_.GetWeakPtr(), true));
724 if (is_online || !is_behind_captive_portal)
725 network_error_model_->HideCaptivePortal();
727 // Hide offline message (if needed) and return if current screen is
728 // not a Gaia frame.
729 if (!is_gaia_signin) {
730 if (!IsSigninScreenHiddenByError())
731 HideOfflineMessage(state, reason);
732 return;
735 // Use the online login page if the user has not used the machine for awhile.
736 if (offline_login_active_)
737 gaia_screen_handler_->MonitorOfflineIdle(is_online);
739 // Reload frame if network state is changed from {!ONLINE} -> ONLINE state.
740 if (reason == NetworkError::ERROR_REASON_NETWORK_STATE_CHANGED &&
741 from_not_online_to_online_transition) {
742 // Schedules a immediate retry.
743 LOG(WARNING) << "Retry frame load since network has been changed.";
744 gaia_reload_reason_ = reason;
745 reload_gaia.ScheduleCall();
748 if (reason == NetworkError::ERROR_REASON_PROXY_CONFIG_CHANGED &&
749 error_screen_should_overlay) {
750 // Schedules a immediate retry.
751 LOG(WARNING) << "Retry frameload since proxy settings has been changed.";
752 gaia_reload_reason_ = reason;
753 reload_gaia.ScheduleCall();
756 if (reason == NetworkError::ERROR_REASON_FRAME_ERROR &&
757 reason != gaia_reload_reason_ &&
758 !IsProxyError(state, reason, FrameError())) {
759 LOG(WARNING) << "Retry frame load due to reason: "
760 << NetworkError::ErrorReasonString(reason);
761 gaia_reload_reason_ = reason;
762 reload_gaia.ScheduleCall();
765 if (is_gaia_loading_timeout) {
766 LOG(WARNING) << "Retry frame load due to loading timeout.";
767 LOG(ERROR) << "UpdateStateInternal reload 4";
768 reload_gaia.ScheduleCall();
771 if ((!is_online || is_gaia_loading_timeout || is_gaia_error) &&
772 !offline_login_active_) {
773 SetupAndShowOfflineMessage(state, reason);
774 } else {
775 HideOfflineMessage(state, reason);
777 // Cancel scheduled GAIA reload (if any) to prevent double reloads.
778 reload_gaia.CancelScheduledCall();
782 void SigninScreenHandler::SetupAndShowOfflineMessage(
783 NetworkStateInformer::State state,
784 NetworkError::ErrorReason reason) {
785 const std::string network_path = network_state_informer_->network_path();
786 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
787 const bool is_proxy_error = IsProxyError(state, reason, FrameError());
788 const bool is_gaia_loading_timeout =
789 (reason == NetworkError::ERROR_REASON_LOADING_TIMEOUT);
791 if (is_proxy_error) {
792 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PROXY,
793 std::string());
794 } else if (is_behind_captive_portal) {
795 // Do not bother a user with obsessive captive portal showing. This
796 // check makes captive portal being shown only once: either when error
797 // screen is shown for the first time or when switching from another
798 // error screen (offline, proxy).
799 if (IsGaiaVisible() || (network_error_model_->GetErrorState() !=
800 NetworkError::ERROR_STATE_PORTAL)) {
801 network_error_model_->FixCaptivePortal();
803 const std::string network_name = GetNetworkName(network_path);
804 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PORTAL,
805 network_name);
806 } else if (is_gaia_loading_timeout) {
807 network_error_model_->SetErrorState(
808 NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT, std::string());
809 } else {
810 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_OFFLINE,
811 std::string());
814 const bool guest_signin_allowed =
815 IsGuestSigninAllowed() &&
816 IsSigninScreenError(network_error_model_->GetErrorState());
817 network_error_model_->AllowGuestSignin(guest_signin_allowed);
819 const bool offline_login_allowed =
820 IsOfflineLoginAllowed() &&
821 IsSigninScreenError(network_error_model_->GetErrorState()) &&
822 network_error_model_->GetErrorState() !=
823 NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT;
824 network_error_model_->AllowOfflineLogin(offline_login_allowed);
826 if (GetCurrentScreen() != OobeUI::SCREEN_ERROR_MESSAGE) {
827 network_error_model_->SetUIState(NetworkError::UI_STATE_SIGNIN);
828 network_error_model_->SetParentScreen(OobeUI::SCREEN_GAIA_SIGNIN);
829 network_error_model_->Show();
830 histogram_helper_->OnErrorShow(network_error_model_->GetErrorState());
834 void SigninScreenHandler::HideOfflineMessage(NetworkStateInformer::State state,
835 NetworkError::ErrorReason reason) {
836 if (!IsSigninScreenHiddenByError())
837 return;
839 gaia_reload_reason_ = NetworkError::ERROR_REASON_NONE;
841 network_error_model_->Hide();
842 histogram_helper_->OnErrorHide();
844 // Forces a reload for Gaia screen on hiding error message.
845 if (IsGaiaVisible() || IsGaiaHiddenByError())
846 ReloadGaia(reason == NetworkError::ERROR_REASON_NETWORK_STATE_CHANGED);
849 void SigninScreenHandler::ReloadGaia(bool force_reload) {
850 gaia_screen_handler_->ReloadGaia(force_reload);
853 void SigninScreenHandler::Initialize() {
854 // If delegate_ is NULL here (e.g. WebUIScreenLocker has been destroyed),
855 // don't do anything, just return.
856 if (!delegate_)
857 return;
859 if (show_on_init_) {
860 show_on_init_ = false;
861 ShowImpl();
865 gfx::NativeWindow SigninScreenHandler::GetNativeWindow() {
866 if (native_window_delegate_)
867 return native_window_delegate_->GetNativeWindow();
868 return NULL;
871 void SigninScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
872 registry->RegisterDictionaryPref(prefs::kUsersLRUInputMethod);
875 void SigninScreenHandler::OnCurrentScreenChanged(OobeUI::Screen current_screen,
876 OobeUI::Screen new_screen) {
877 if (new_screen == OobeUI::SCREEN_ACCOUNT_PICKER) {
878 // Restore active IME state if returning to user pod row screen.
879 input_method::InputMethodManager::Get()->SetState(ime_state_);
883 void SigninScreenHandler::ClearAndEnablePassword() {
884 core_oobe_actor_->ResetSignInUI(false);
887 void SigninScreenHandler::ClearUserPodPassword() {
888 core_oobe_actor_->ClearUserPodPassword();
891 void SigninScreenHandler::RefocusCurrentPod() {
892 core_oobe_actor_->RefocusCurrentPod();
895 void SigninScreenHandler::OnUserRemoved(const std::string& username) {
896 CallJS("login.AccountPickerScreen.removeUser", username);
897 if (delegate_->GetUsers().empty())
898 OnShowAddUser();
901 void SigninScreenHandler::OnUserImageChanged(const user_manager::User& user) {
902 if (page_is_ready())
903 CallJS("login.AccountPickerScreen.updateUserImage", user.email());
906 void SigninScreenHandler::OnPreferencesChanged() {
907 // Make sure that one of the login UI is fully functional now, otherwise
908 // preferences update would be picked up next time it will be shown.
909 if (!webui_visible_) {
910 LOG(WARNING) << "Login UI is not active - postponed prefs change.";
911 preferences_changed_delayed_ = true;
912 return;
915 if (delegate_ && !delegate_->IsShowUsers()) {
916 HandleShowAddUser(NULL);
917 } else {
918 if (delegate_)
919 delegate_->HandleGetUsers();
920 UpdateUIState(UI_STATE_ACCOUNT_PICKER, NULL);
922 preferences_changed_delayed_ = false;
925 void SigninScreenHandler::ResetSigninScreenHandlerDelegate() {
926 SetDelegate(NULL);
929 void SigninScreenHandler::ShowError(int login_attempts,
930 const std::string& error_text,
931 const std::string& help_link_text,
932 HelpAppLauncher::HelpTopic help_topic_id) {
933 core_oobe_actor_->ShowSignInError(login_attempts, error_text, help_link_text,
934 help_topic_id);
937 void SigninScreenHandler::ShowErrorScreen(LoginDisplay::SigninError error_id) {
938 switch (error_id) {
939 case LoginDisplay::TPM_ERROR:
940 core_oobe_actor_->ShowTpmError();
941 break;
942 default:
943 NOTREACHED() << "Unknown sign in error";
944 break;
948 void SigninScreenHandler::ShowSigninUI(const std::string& email) {
949 core_oobe_actor_->ShowSignInUI(email);
952 void SigninScreenHandler::ShowPasswordChangedDialog(bool show_password_error,
953 const std::string& email) {
954 core_oobe_actor_->ShowPasswordChangedScreen(show_password_error, email);
957 void SigninScreenHandler::ShowSigninScreenForCreds(
958 const std::string& username,
959 const std::string& password) {
960 DCHECK(gaia_screen_handler_);
961 gaia_screen_handler_->ShowSigninScreenForCreds(username, password);
964 void SigninScreenHandler::ShowWhitelistCheckFailedError() {
965 DCHECK(gaia_screen_handler_);
966 gaia_screen_handler_->ShowWhitelistCheckFailedError();
969 void SigninScreenHandler::Observe(int type,
970 const content::NotificationSource& source,
971 const content::NotificationDetails& details) {
972 switch (type) {
973 case chrome::NOTIFICATION_AUTH_NEEDED: {
974 has_pending_auth_ui_ = true;
975 break;
977 case chrome::NOTIFICATION_AUTH_SUPPLIED:
978 has_pending_auth_ui_ = false;
979 // Reload auth extension as proxy credentials are supplied.
980 if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
981 ReloadGaia(true);
982 update_state_closure_.Cancel();
983 break;
984 case chrome::NOTIFICATION_AUTH_CANCELLED: {
985 // Don't reload auth extension if proxy auth dialog was cancelled.
986 has_pending_auth_ui_ = false;
987 update_state_closure_.Cancel();
988 break;
990 default:
991 NOTREACHED() << "Unexpected notification " << type;
995 void SigninScreenHandler::OnMaximizeModeStarted() {
996 CallJS("login.AccountPickerScreen.setTouchViewState", true);
999 void SigninScreenHandler::OnMaximizeModeEnded() {
1000 CallJS("login.AccountPickerScreen.setTouchViewState", false);
1003 bool SigninScreenHandler::ShouldLoadGaia() const {
1004 // Fetching of the extension is not started before account picker page is
1005 // loaded because it can affect the loading speed.
1006 // Do not load the extension for the screen locker, see crosbug.com/25018.
1007 return !ScreenLocker::default_screen_locker() &&
1008 is_account_picker_showing_first_time_;
1011 void SigninScreenHandler::UserSettingsChanged() {
1012 DCHECK(gaia_screen_handler_);
1013 GaiaContext context;
1014 if (delegate_)
1015 context.has_users = !delegate_->GetUsers().empty();
1016 gaia_screen_handler_->UpdateGaia(context);
1017 UpdateAddButtonStatus();
1020 void SigninScreenHandler::UpdateAddButtonStatus() {
1021 CallJS("cr.ui.login.DisplayManager.updateAddUserButtonStatus",
1022 AllWhitelistedUsersPresent());
1025 void SigninScreenHandler::HandleAuthenticateUser(const std::string& username,
1026 const std::string& password) {
1027 if (!delegate_)
1028 return;
1029 UserContext user_context(gaia::SanitizeEmail(username));
1030 user_context.SetKey(Key(password));
1031 delegate_->Login(user_context, SigninSpecifics());
1034 void SigninScreenHandler::HandleLaunchIncognito() {
1035 UserContext context(user_manager::USER_TYPE_GUEST, std::string());
1036 if (delegate_)
1037 delegate_->Login(context, SigninSpecifics());
1040 void SigninScreenHandler::HandleShowSupervisedUserCreationScreen() {
1041 if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
1042 LOG(ERROR) << "Managed users not allowed.";
1043 return;
1045 LoginDisplayHostImpl::default_host()->
1046 StartWizard(WizardController::kSupervisedUserCreationScreenName);
1049 void SigninScreenHandler::HandleLaunchPublicSession(
1050 const std::string& user_id,
1051 const std::string& locale,
1052 const std::string& input_method) {
1053 if (!delegate_)
1054 return;
1056 UserContext context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user_id);
1057 context.SetPublicSessionLocale(locale),
1058 context.SetPublicSessionInputMethod(input_method);
1059 delegate_->Login(context, SigninSpecifics());
1062 void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) {
1063 if (!delegate_ || delegate_->IsShowUsers()) {
1064 NOTREACHED();
1065 return;
1067 std::string email;
1068 args->GetString(0, &email);
1070 gaia_screen_handler_->PopulateEmail(email);
1071 // Load auth extension. Parameters are: force reload, do not load extension in
1072 // background, use offline version.
1073 gaia_screen_handler_->LoadAuthExtension(true, false, true);
1074 UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL);
1077 void SigninScreenHandler::HandleShutdownSystem() {
1078 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
1081 void SigninScreenHandler::HandleLoadWallpaper(const std::string& email) {
1082 if (delegate_)
1083 delegate_->LoadWallpaper(email);
1086 void SigninScreenHandler::HandleRebootSystem() {
1087 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
1090 void SigninScreenHandler::HandleRemoveUser(const std::string& email) {
1091 if (!delegate_)
1092 return;
1093 delegate_->RemoveUser(email);
1094 UpdateAddButtonStatus();
1097 void SigninScreenHandler::HandleShowAddUser(const base::ListValue* args) {
1098 TRACE_EVENT_ASYNC_STEP_INTO0("ui",
1099 "ShowLoginWebUI",
1100 LoginDisplayHostImpl::kShowLoginWebUIid,
1101 "ShowAddUser");
1102 std::string email;
1103 // |args| can be null if it's OOBE.
1104 if (args)
1105 args->GetString(0, &email);
1106 gaia_screen_handler_->PopulateEmail(email);
1107 if (!email.empty())
1108 SendReauthReason(email);
1109 OnShowAddUser();
1112 void SigninScreenHandler::HandleToggleEnrollmentScreen() {
1113 if (delegate_)
1114 delegate_->ShowEnterpriseEnrollmentScreen();
1117 void SigninScreenHandler::HandleToggleEnableDebuggingScreen() {
1118 if (delegate_)
1119 delegate_->ShowEnableDebuggingScreen();
1122 void SigninScreenHandler::HandleToggleKioskEnableScreen() {
1123 policy::BrowserPolicyConnectorChromeOS* connector =
1124 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1125 if (delegate_ && !connector->IsEnterpriseManaged() &&
1126 LoginDisplayHostImpl::default_host()) {
1127 delegate_->ShowKioskEnableScreen();
1131 void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() {
1132 policy::BrowserPolicyConnectorChromeOS* connector =
1133 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1134 if (delegate_ && !connector->IsEnterpriseManaged())
1135 delegate_->ShowKioskAutolaunchScreen();
1138 void SigninScreenHandler::LoadUsers(const base::ListValue& users_list,
1139 bool showGuest) {
1140 CallJS("login.AccountPickerScreen.loadUsers",
1141 users_list,
1142 delegate_->IsShowGuest());
1145 void SigninScreenHandler::HandleAccountPickerReady() {
1146 VLOG(0) << "Login WebUI >> AccountPickerReady";
1148 if (delegate_ && !ScreenLocker::default_screen_locker() &&
1149 !chromeos::IsMachineHWIDCorrect() &&
1150 !oobe_ui_) {
1151 delegate_->ShowWrongHWIDScreen();
1152 return;
1155 PrefService* prefs = g_browser_process->local_state();
1156 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
1157 if (core_oobe_actor_)
1158 core_oobe_actor_->ShowDeviceResetScreen();
1160 return;
1161 } else if (prefs->GetBoolean(prefs::kDebuggingFeaturesRequested)) {
1162 if (core_oobe_actor_)
1163 core_oobe_actor_->ShowEnableDebuggingScreen();
1165 return;
1168 is_account_picker_showing_first_time_ = true;
1170 if (delegate_)
1171 delegate_->OnSigninScreenReady();
1174 void SigninScreenHandler::HandleWallpaperReady() {
1175 if (ScreenLocker::default_screen_locker()) {
1176 ScreenLocker::default_screen_locker()->delegate()->
1177 OnLockBackgroundDisplayed();
1181 void SigninScreenHandler::HandleSignOutUser() {
1182 if (delegate_)
1183 delegate_->Signout();
1186 void SigninScreenHandler::HandleCreateAccount() {
1187 if (delegate_)
1188 delegate_->CreateAccount();
1191 void SigninScreenHandler::HandleOpenProxySettings() {
1192 LoginDisplayHostImpl::default_host()->OpenProxySettings();
1195 void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
1196 VLOG(1) << "Login WebUI >> loginVisible, src: " << source << ", "
1197 << "webui_visible_: " << webui_visible_;
1198 if (!webui_visible_) {
1199 // There might be multiple messages from OOBE UI so send notifications after
1200 // the first one only.
1201 content::NotificationService::current()->Notify(
1202 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
1203 content::NotificationService::AllSources(),
1204 content::NotificationService::NoDetails());
1205 TRACE_EVENT_ASYNC_END0(
1206 "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid);
1208 webui_visible_ = true;
1209 if (preferences_changed_delayed_)
1210 OnPreferencesChanged();
1213 void SigninScreenHandler::HandleCancelPasswordChangedFlow(
1214 const std::string& user_id) {
1215 if (!user_id.empty())
1216 RecordReauthReason(user_id, ReauthReason::PASSWORD_UPDATE_SKIPPED);
1217 gaia_screen_handler_->StartClearingCookies(
1218 base::Bind(&SigninScreenHandler::CancelPasswordChangedFlowInternal,
1219 weak_factory_.GetWeakPtr()));
1222 void SigninScreenHandler::HandleCancelUserAdding() {
1223 if (delegate_)
1224 delegate_->CancelUserAdding();
1227 void SigninScreenHandler::HandleMigrateUserData(
1228 const std::string& old_password) {
1229 if (delegate_)
1230 delegate_->MigrateUserData(old_password);
1233 void SigninScreenHandler::HandleResyncUserData() {
1234 if (delegate_)
1235 delegate_->ResyncUserData();
1238 void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source,
1239 bool active) {
1240 VLOG(0) << "Login WebUI >> active: " << active << ", "
1241 << "source: " << source;
1243 if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() &&
1244 KioskAppManager::Get()->IsAutoLaunchRequested()) {
1245 VLOG(0) << "Showing auto-launch warning";
1246 // On slow devices, the wallpaper animation is not shown initially, so we
1247 // must explicitly load the wallpaper. This is also the case for the
1248 // account-picker and gaia-signin UI states.
1249 delegate_->LoadSigninWallpaper();
1250 HandleToggleKioskAutolaunchScreen();
1251 return;
1254 if (source == kSourceGaiaSignin) {
1255 ui_state_ = UI_STATE_GAIA_SIGNIN;
1256 } else if (source == kSourceAccountPicker) {
1257 ui_state_ = UI_STATE_ACCOUNT_PICKER;
1258 } else {
1259 NOTREACHED();
1260 return;
1264 void SigninScreenHandler::HandleUnlockOnLoginSuccess() {
1265 DCHECK(user_manager::UserManager::Get()->IsUserLoggedIn());
1266 if (ScreenLocker::default_screen_locker())
1267 ScreenLocker::default_screen_locker()->UnlockOnLoginSuccess();
1270 void SigninScreenHandler::HandleShowLoadingTimeoutError() {
1271 UpdateState(NetworkError::ERROR_REASON_LOADING_TIMEOUT);
1274 void SigninScreenHandler::HandleUpdateOfflineLogin(bool offline_login_active) {
1275 offline_login_active_ = offline_login_active;
1278 void SigninScreenHandler::HandleFocusPod(const std::string& user_id) {
1279 SetUserInputMethod(user_id, ime_state_.get());
1280 WallpaperManager::Get()->SetUserWallpaperDelayed(user_id);
1281 proximity_auth::ScreenlockBridge::Get()->SetFocusedUser(user_id);
1282 if (delegate_)
1283 delegate_->CheckUserStatus(user_id);
1284 if (!test_focus_pod_callback_.is_null())
1285 test_focus_pod_callback_.Run();
1287 bool use_24hour_clock = false;
1288 if (user_manager::UserManager::Get()->GetKnownUserBooleanPref(
1289 user_id, prefs::kUse24HourClock, &use_24hour_clock)) {
1290 g_browser_process->platform_part()
1291 ->GetSystemClock()
1292 ->SetLastFocusedPodHourClockType(use_24hour_clock ? base::k24HourClock
1293 : base::k12HourClock);
1297 void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
1298 const std::string& user_id,
1299 const std::string& locale) {
1300 GetKeyboardLayoutsForLocale(
1301 base::Bind(&SigninScreenHandler::SendPublicSessionKeyboardLayouts,
1302 weak_factory_.GetWeakPtr(),
1303 user_id,
1304 locale),
1305 locale);
1308 void SigninScreenHandler::SendPublicSessionKeyboardLayouts(
1309 const std::string& user_id,
1310 const std::string& locale,
1311 scoped_ptr<base::ListValue> keyboard_layouts) {
1312 CallJS("login.AccountPickerScreen.setPublicSessionKeyboardLayouts",
1313 user_id,
1314 locale,
1315 *keyboard_layouts);
1318 void SigninScreenHandler::HandleLaunchKioskApp(const std::string& app_id,
1319 bool diagnostic_mode) {
1320 UserContext context(user_manager::USER_TYPE_KIOSK_APP, app_id);
1321 SigninSpecifics specifics;
1322 specifics.kiosk_diagnostic_mode = diagnostic_mode;
1323 if (delegate_)
1324 delegate_->Login(context, specifics);
1327 void SigninScreenHandler::HandleCancelConsumerManagementEnrollment() {
1328 policy::ConsumerManagementService* consumer_management =
1329 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
1330 GetConsumerManagementService();
1331 CHECK(consumer_management);
1332 consumer_management->SetStage(
1333 policy::ConsumerManagementStage::EnrollmentCanceled());
1334 is_enrolling_consumer_management_ = false;
1335 ShowImpl();
1338 void SigninScreenHandler::HandleGetTouchViewState() {
1339 if (max_mode_delegate_) {
1340 CallJS("login.AccountPickerScreen.setTouchViewState",
1341 max_mode_delegate_->IsMaximizeModeEnabled());
1345 void SigninScreenHandler::HandleLogRemoveUserWarningShown() {
1346 ProfileMetrics::LogProfileDeleteUser(
1347 ProfileMetrics::DELETE_PROFILE_USER_MANAGER_SHOW_WARNING);
1350 void SigninScreenHandler::HandleFirstIncorrectPasswordAttempt(
1351 const std::string& email) {
1352 // TODO(ginkage): Fix this case once crbug.com/469987 is ready.
1354 if (user_manager::UserManager::Get()->FindUsingSAML(email))
1355 RecordReauthReason(email, ReauthReason::INCORRECT_SAML_PASSWORD_ENTERED);
1359 void SigninScreenHandler::HandleMaxIncorrectPasswordAttempts(
1360 const std::string& email) {
1361 RecordReauthReason(email, ReauthReason::INCORRECT_PASSWORD_ENTERED);
1364 bool SigninScreenHandler::AllWhitelistedUsersPresent() {
1365 CrosSettings* cros_settings = CrosSettings::Get();
1366 bool allow_new_user = false;
1367 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
1368 if (allow_new_user)
1369 return false;
1370 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1371 const user_manager::UserList& users = user_manager->GetUsers();
1372 if (!delegate_ || users.size() > kMaxUsers) {
1373 return false;
1375 const base::ListValue* whitelist = NULL;
1376 if (!cros_settings->GetList(kAccountsPrefUsers, &whitelist) || !whitelist)
1377 return false;
1378 for (size_t i = 0; i < whitelist->GetSize(); ++i) {
1379 std::string whitelisted_user;
1380 // NB: Wildcards in the whitelist are also detected as not present here.
1381 if (!whitelist->GetString(i, &whitelisted_user) ||
1382 !user_manager->IsKnownUser(whitelisted_user)) {
1383 return false;
1386 return true;
1389 void SigninScreenHandler::CancelPasswordChangedFlowInternal() {
1390 if (delegate_) {
1391 ShowImpl();
1392 delegate_->CancelPasswordChangedFlow();
1396 OobeUI* SigninScreenHandler::GetOobeUI() const {
1397 return static_cast<OobeUI*>(web_ui()->GetController());
1400 OobeUI::Screen SigninScreenHandler::GetCurrentScreen() const {
1401 OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
1402 OobeUI* oobe_ui = GetOobeUI();
1403 if (oobe_ui)
1404 screen = oobe_ui->current_screen();
1405 return screen;
1408 bool SigninScreenHandler::IsGaiaVisible() const {
1409 return IsSigninScreen(GetCurrentScreen()) &&
1410 ui_state_ == UI_STATE_GAIA_SIGNIN;
1413 bool SigninScreenHandler::IsGaiaHiddenByError() const {
1414 return IsSigninScreenHiddenByError() &&
1415 ui_state_ == UI_STATE_GAIA_SIGNIN;
1418 bool SigninScreenHandler::IsSigninScreenHiddenByError() const {
1419 return (GetCurrentScreen() == OobeUI::SCREEN_ERROR_MESSAGE) &&
1420 (IsSigninScreen(network_error_model_->GetParentScreen()));
1423 bool SigninScreenHandler::IsGuestSigninAllowed() const {
1424 CrosSettings* cros_settings = CrosSettings::Get();
1425 if (!cros_settings)
1426 return false;
1427 bool allow_guest;
1428 cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
1429 return allow_guest;
1432 bool SigninScreenHandler::IsOfflineLoginAllowed() const {
1433 CrosSettings* cros_settings = CrosSettings::Get();
1434 if (!cros_settings)
1435 return false;
1437 // Offline login is allowed only when user pods are hidden.
1438 bool show_pods;
1439 cros_settings->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_pods);
1440 return !show_pods;
1443 void SigninScreenHandler::OnShowAddUser() {
1444 is_account_picker_showing_first_time_ = false;
1445 DCHECK(gaia_screen_handler_);
1446 gaia_screen_handler_->ShowGaiaAsync(is_enrolling_consumer_management_);
1449 net::Error SigninScreenHandler::FrameError() const {
1450 DCHECK(gaia_screen_handler_);
1451 return gaia_screen_handler_->frame_error();
1454 void SigninScreenHandler::OnCapsLockChanged(bool enabled) {
1455 caps_lock_enabled_ = enabled;
1456 if (page_is_ready())
1457 CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_);
1460 } // namespace chromeos