ProfilePolicyConnectorFactory: Refactoring from Profile to BrowserContext.
[chromium-blink-merge.git] / chrome / browser / ui / webui / chromeos / login / signin_screen_handler.cc
blob6d72a2da350de508f8344210d5cd3c548ce60185
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/wm/lock_state_controller.h"
12 #include "base/bind.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/metrics/histogram.h"
16 #include "base/prefs/pref_registry_simple.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/prefs/scoped_user_pref_update.h"
19 #include "base/strings/string16.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/sys_info.h"
24 #include "base/trace_event/trace_event.h"
25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/browser_process_platform_part_chromeos.h"
27 #include "chrome/browser/browser_shutdown.h"
28 #include "chrome/browser/chrome_notification_types.h"
29 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
30 #include "chrome/browser/chromeos/input_method/input_method_util.h"
31 #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
32 #include "chrome/browser/chromeos/login/hwid_checker.h"
33 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
34 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
35 #include "chrome/browser/chromeos/login/screens/network_error.h"
36 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
37 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
38 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
39 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
40 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
41 #include "chrome/browser/chromeos/login/wizard_controller.h"
42 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
43 #include "chrome/browser/chromeos/policy/consumer_management_service.h"
44 #include "chrome/browser/chromeos/policy/consumer_management_stage.h"
45 #include "chrome/browser/chromeos/policy/device_local_account.h"
46 #include "chrome/browser/chromeos/profiles/profile_helper.h"
47 #include "chrome/browser/chromeos/settings/cros_settings.h"
48 #include "chrome/browser/io_thread.h"
49 #include "chrome/browser/profiles/profile.h"
50 #include "chrome/browser/signin/easy_unlock_service.h"
51 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
52 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
53 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
54 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
55 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
56 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
57 #include "chrome/common/pref_names.h"
58 #include "chrome/common/url_constants.h"
59 #include "chrome/grit/chromium_strings.h"
60 #include "chrome/grit/generated_resources.h"
61 #include "chromeos/dbus/dbus_thread_manager.h"
62 #include "chromeos/dbus/power_manager_client.h"
63 #include "chromeos/login/auth/key.h"
64 #include "chromeos/login/auth/user_context.h"
65 #include "chromeos/network/network_state.h"
66 #include "chromeos/network/network_state_handler.h"
67 #include "chromeos/network/portal_detector/network_portal_detector.h"
68 #include "components/login/localized_values_builder.h"
69 #include "components/user_manager/user.h"
70 #include "components/user_manager/user_manager.h"
71 #include "components/user_manager/user_type.h"
72 #include "content/public/browser/render_frame_host.h"
73 #include "content/public/browser/web_contents.h"
74 #include "google_apis/gaia/gaia_auth_util.h"
75 #include "third_party/cros_system_api/dbus/service_constants.h"
76 #include "ui/base/ime/chromeos/ime_keyboard.h"
77 #include "ui/base/ime/chromeos/input_method_descriptor.h"
78 #include "ui/base/ime/chromeos/input_method_manager.h"
79 #include "ui/base/webui/web_ui_util.h"
81 namespace {
83 // Max number of users to show.
84 const size_t kMaxUsers = 18;
86 // Timeout to delay first notification about offline state for a
87 // current network.
88 const int kOfflineTimeoutSec = 5;
90 // Timeout used to prevent infinite connecting to a flaky network.
91 const int kConnectingTimeoutSec = 60;
93 // Type of the login screen UI that is currently presented to user.
94 const char kSourceGaiaSignin[] = "gaia-signin";
95 const char kSourceAccountPicker[] = "account-picker";
97 static bool Contains(const std::vector<std::string>& container,
98 const std::string& value) {
99 return std::find(container.begin(), container.end(), value) !=
100 container.end();
103 class CallOnReturn {
104 public:
105 explicit CallOnReturn(const base::Closure& callback)
106 : callback_(callback), call_scheduled_(false) {}
108 ~CallOnReturn() {
109 if (call_scheduled_ && !callback_.is_null())
110 callback_.Run();
113 void ScheduleCall() { call_scheduled_ = true; }
115 private:
116 base::Closure callback_;
117 bool call_scheduled_;
119 DISALLOW_COPY_AND_ASSIGN(CallOnReturn);
122 } // namespace
124 namespace chromeos {
126 namespace {
128 bool IsOnline(NetworkStateInformer::State state,
129 NetworkError::ErrorReason reason) {
130 return state == NetworkStateInformer::ONLINE &&
131 reason != NetworkError::ERROR_REASON_PORTAL_DETECTED &&
132 reason != NetworkError::ERROR_REASON_LOADING_TIMEOUT;
135 bool IsBehindCaptivePortal(NetworkStateInformer::State state,
136 NetworkError::ErrorReason reason) {
137 return state == NetworkStateInformer::CAPTIVE_PORTAL ||
138 reason == NetworkError::ERROR_REASON_PORTAL_DETECTED;
141 bool IsProxyError(NetworkStateInformer::State state,
142 NetworkError::ErrorReason reason,
143 net::Error frame_error) {
144 return state == NetworkStateInformer::PROXY_AUTH_REQUIRED ||
145 reason == NetworkError::ERROR_REASON_PROXY_AUTH_CANCELLED ||
146 reason == NetworkError::ERROR_REASON_PROXY_CONNECTION_FAILED ||
147 (reason == NetworkError::ERROR_REASON_FRAME_ERROR &&
148 (frame_error == net::ERR_PROXY_CONNECTION_FAILED ||
149 frame_error == net::ERR_TUNNEL_CONNECTION_FAILED));
152 bool IsSigninScreen(const OobeUI::Screen screen) {
153 return screen == OobeUI::SCREEN_GAIA_SIGNIN ||
154 screen == OobeUI::SCREEN_ACCOUNT_PICKER;
157 bool IsSigninScreenError(NetworkError::ErrorState error_state) {
158 return error_state == NetworkError::ERROR_STATE_PORTAL ||
159 error_state == NetworkError::ERROR_STATE_OFFLINE ||
160 error_state == NetworkError::ERROR_STATE_PROXY ||
161 error_state == NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT;
164 // Returns network name by service path.
165 std::string GetNetworkName(const std::string& service_path) {
166 const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
167 GetNetworkState(service_path);
168 if (!network)
169 return std::string();
170 return network->name();
173 static bool SetUserInputMethodImpl(
174 const std::string& username,
175 const std::string& user_input_method,
176 input_method::InputMethodManager::State* ime_state) {
177 if (!chromeos::input_method::InputMethodManager::Get()->IsLoginKeyboard(
178 user_input_method)) {
179 LOG(WARNING) << "SetUserInputMethod('" << username
180 << "'): stored user LRU input method '" << user_input_method
181 << "' is no longer Full Latin Keyboard Language"
182 << " (entry dropped). Use hardware default instead.";
184 PrefService* const local_state = g_browser_process->local_state();
185 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
187 base::DictionaryValue* const users_lru_input_methods = updater.Get();
188 if (users_lru_input_methods != NULL) {
189 users_lru_input_methods->SetStringWithoutPathExpansion(username, "");
191 return false;
194 if (!Contains(ime_state->GetActiveInputMethodIds(), user_input_method)) {
195 if (!ime_state->EnableInputMethod(user_input_method)) {
196 DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username
197 << "'): user input method '" << user_input_method
198 << "' is not enabled and enabling failed (ignored!).";
201 ime_state->ChangeInputMethod(user_input_method, false /* show_message */);
203 return true;
206 } // namespace
208 // LoginScreenContext implementation ------------------------------------------
210 LoginScreenContext::LoginScreenContext() {
211 Init();
214 LoginScreenContext::LoginScreenContext(const base::ListValue* args) {
215 Init();
217 if (!args || args->GetSize() == 0)
218 return;
219 std::string email;
220 if (args->GetString(0, &email))
221 email_ = email;
224 void LoginScreenContext::Init() {
225 oobe_ui_ = false;
228 // SigninScreenHandler implementation ------------------------------------------
230 SigninScreenHandler::SigninScreenHandler(
231 const scoped_refptr<NetworkStateInformer>& network_state_informer,
232 NetworkErrorModel* network_error_model,
233 CoreOobeActor* core_oobe_actor,
234 GaiaScreenHandler* gaia_screen_handler)
235 : network_state_informer_(network_state_informer),
236 network_error_model_(network_error_model),
237 core_oobe_actor_(core_oobe_actor),
238 caps_lock_enabled_(chromeos::input_method::InputMethodManager::Get()
239 ->GetImeKeyboard()
240 ->CapsLockIsEnabled()),
241 gaia_screen_handler_(gaia_screen_handler),
242 histogram_helper_(new ErrorScreensHistogramHelper("Signin")),
243 weak_factory_(this) {
244 DCHECK(network_state_informer_.get());
245 DCHECK(network_error_model_);
246 DCHECK(core_oobe_actor_);
247 DCHECK(gaia_screen_handler_);
248 gaia_screen_handler_->SetSigninScreenHandler(this);
249 network_state_informer_->AddObserver(this);
251 registrar_.Add(this,
252 chrome::NOTIFICATION_AUTH_NEEDED,
253 content::NotificationService::AllSources());
254 registrar_.Add(this,
255 chrome::NOTIFICATION_AUTH_SUPPLIED,
256 content::NotificationService::AllSources());
257 registrar_.Add(this,
258 chrome::NOTIFICATION_AUTH_CANCELLED,
259 content::NotificationService::AllSources());
261 chromeos::input_method::ImeKeyboard* keyboard =
262 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
263 if (keyboard)
264 keyboard->AddObserver(this);
266 max_mode_delegate_.reset(new TouchViewControllerDelegate());
267 max_mode_delegate_->AddObserver(this);
269 policy::ConsumerManagementService* consumer_management =
270 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
271 GetConsumerManagementService();
272 is_enrolling_consumer_management_ =
273 consumer_management &&
274 consumer_management->GetStage().IsEnrollmentRequested();
277 SigninScreenHandler::~SigninScreenHandler() {
278 OobeUI* oobe_ui = GetOobeUI();
279 if (oobe_ui && oobe_ui_observer_added_)
280 oobe_ui->RemoveObserver(this);
281 chromeos::input_method::ImeKeyboard* keyboard =
282 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
283 if (keyboard)
284 keyboard->RemoveObserver(this);
285 weak_factory_.InvalidateWeakPtrs();
286 if (delegate_)
287 delegate_->SetWebUIHandler(NULL);
288 network_state_informer_->RemoveObserver(this);
289 if (max_mode_delegate_) {
290 max_mode_delegate_->RemoveObserver(this);
291 max_mode_delegate_.reset(NULL);
293 ScreenlockBridge::Get()->SetLockHandler(NULL);
294 ScreenlockBridge::Get()->SetFocusedUser("");
297 // static
298 std::string SigninScreenHandler::GetUserLRUInputMethod(
299 const std::string& username) {
300 PrefService* const local_state = g_browser_process->local_state();
301 const base::DictionaryValue* users_lru_input_methods =
302 local_state->GetDictionary(prefs::kUsersLRUInputMethod);
304 if (!users_lru_input_methods) {
305 DLOG(WARNING) << "GetUserLRUInputMethod('" << username
306 << "'): no kUsersLRUInputMethod";
307 return std::string();
310 std::string input_method;
312 if (!users_lru_input_methods->GetStringWithoutPathExpansion(username,
313 &input_method)) {
314 DVLOG(0) << "GetUserLRUInputMethod('" << username
315 << "'): no input method for this user";
316 return std::string();
319 return input_method;
322 // static
323 // Update keyboard layout to least recently used by the user.
324 void SigninScreenHandler::SetUserInputMethod(
325 const std::string& username,
326 input_method::InputMethodManager::State* ime_state) {
327 bool succeed = false;
329 const std::string input_method = GetUserLRUInputMethod(username);
331 if (!input_method.empty())
332 succeed = SetUserInputMethodImpl(username, input_method, ime_state);
334 // This is also a case when LRU layout is set only for a few local users,
335 // thus others need to be switched to default locale.
336 // Otherwise they will end up using another user's locale to log in.
337 if (!succeed) {
338 DVLOG(0) << "SetUserInputMethod('" << username
339 << "'): failed to set user layout. Switching to default.";
341 ime_state->SetInputMethodLoginDefault();
345 void SigninScreenHandler::DeclareLocalizedValues(
346 ::login::LocalizedValuesBuilder* builder) {
347 builder->Add("passwordHint", IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT);
348 builder->Add("signingIn", IDS_LOGIN_POD_SIGNING_IN);
349 builder->Add("podMenuButtonAccessibleName",
350 IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME);
351 builder->Add("podMenuRemoveItemAccessibleName",
352 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME);
353 builder->Add("passwordFieldAccessibleName",
354 IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME);
355 builder->Add("signedIn", IDS_SCREEN_LOCK_ACTIVE_USER);
356 builder->Add("signinButton", IDS_LOGIN_BUTTON);
357 builder->Add("launchAppButton", IDS_LAUNCH_APP_BUTTON);
358 builder->Add("restart", IDS_RESTART_BUTTON);
359 builder->Add("shutDown", IDS_SHUTDOWN_BUTTON);
360 builder->Add("addUser", IDS_ADD_USER_BUTTON);
361 builder->Add("browseAsGuest", IDS_GO_INCOGNITO_BUTTON);
362 builder->Add("cancel", IDS_CANCEL);
363 builder->Add("signOutUser", IDS_SCREEN_LOCK_SIGN_OUT);
364 builder->Add("offlineLogin", IDS_OFFLINE_LOGIN_HTML);
365 builder->Add("ownerUserPattern", IDS_LOGIN_POD_OWNER_USER);
366 builder->Add("removeUser", IDS_LOGIN_POD_REMOVE_USER);
367 builder->Add("errorTpmFailureTitle", IDS_LOGIN_ERROR_TPM_FAILURE_TITLE);
368 builder->Add("errorTpmFailureReboot", IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT);
369 builder->Add("errorTpmFailureRebootButton",
370 IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT_BUTTON);
372 policy::BrowserPolicyConnectorChromeOS* connector =
373 g_browser_process->platform_part()->browser_policy_connector_chromeos();
374 builder->Add("disabledAddUserTooltip",
375 connector->IsEnterpriseManaged()
376 ? IDS_DISABLED_ADD_USER_TOOLTIP_ENTERPRISE
377 : IDS_DISABLED_ADD_USER_TOOLTIP);
379 builder->Add("supervisedUserExpiredTokenWarning",
380 IDS_SUPERVISED_USER_EXPIRED_TOKEN_WARNING);
381 builder->Add("signinBannerText", IDS_LOGIN_USER_ADDING_BANNER);
383 // Multi-profiles related strings.
384 builder->Add("multiProfilesRestrictedPolicyTitle",
385 IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE);
386 builder->Add("multiProfilesNotAllowedPolicyMsg",
387 IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG);
388 builder->Add("multiProfilesPrimaryOnlyPolicyMsg",
389 IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG);
390 builder->Add("multiProfilesOwnerPrimaryOnlyMsg",
391 IDS_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG);
393 // Strings used by password changed dialog.
394 builder->Add("passwordChangedTitle", IDS_LOGIN_PASSWORD_CHANGED_TITLE);
395 builder->Add("passwordChangedDesc", IDS_LOGIN_PASSWORD_CHANGED_DESC);
396 builder->AddF("passwordChangedMoreInfo",
397 IDS_LOGIN_PASSWORD_CHANGED_MORE_INFO,
398 IDS_SHORT_PRODUCT_OS_NAME);
400 builder->Add("oldPasswordHint", IDS_LOGIN_PASSWORD_CHANGED_OLD_PASSWORD_HINT);
401 builder->Add("oldPasswordIncorrect",
402 IDS_LOGIN_PASSWORD_CHANGED_INCORRECT_OLD_PASSWORD);
403 builder->Add("passwordChangedCantRemember",
404 IDS_LOGIN_PASSWORD_CHANGED_CANT_REMEMBER);
405 builder->Add("passwordChangedBackButton",
406 IDS_LOGIN_PASSWORD_CHANGED_BACK_BUTTON);
407 builder->Add("passwordChangedsOkButton", IDS_OK);
408 builder->Add("passwordChangedProceedAnyway",
409 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY);
410 builder->Add("proceedAnywayButton",
411 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY_BUTTON);
412 builder->Add("publicAccountInfoFormat", IDS_LOGIN_PUBLIC_ACCOUNT_INFO_FORMAT);
413 builder->Add("publicAccountReminder",
414 IDS_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER);
415 builder->Add("publicSessionLanguageAndInput",
416 IDS_LOGIN_PUBLIC_SESSION_LANGUAGE_AND_INPUT);
417 builder->Add("publicAccountEnter", IDS_LOGIN_PUBLIC_ACCOUNT_ENTER);
418 builder->Add("publicAccountEnterAccessibleName",
419 IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME);
420 builder->Add("publicSessionSelectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
421 builder->Add("publicSessionSelectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
422 builder->Add("removeUserWarningText",
423 base::string16());
424 builder->AddF("removeLegacySupervisedUserWarningText",
425 IDS_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING,
426 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL));
427 builder->Add("removeUserWarningButtonTitle",
428 IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON);
430 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE);
432 builder->Add("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE);
433 builder->Add("confirmPasswordLabel", IDS_LOGIN_CONFIRM_PASSWORD_LABEL);
434 builder->Add("confirmPasswordConfirmButton",
435 IDS_LOGIN_CONFIRM_PASSWORD_CONFIRM_BUTTON);
436 builder->Add("confirmPasswordText", IDS_LOGIN_CONFIRM_PASSWORD_TEXT);
437 builder->Add("confirmPasswordErrorText",
438 IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT);
440 builder->Add("fatalEnrollmentError",
441 IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR);
442 builder->Add("insecureURLEnrollmentError",
443 IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR);
446 void SigninScreenHandler::RegisterMessages() {
447 AddCallback("authenticateUser", &SigninScreenHandler::HandleAuthenticateUser);
448 AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito);
449 AddCallback("showSupervisedUserCreationScreen",
450 &SigninScreenHandler::HandleShowSupervisedUserCreationScreen);
451 AddCallback("launchPublicSession",
452 &SigninScreenHandler::HandleLaunchPublicSession);
453 AddRawCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin);
454 AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem);
455 AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser);
456 AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem);
457 AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper);
458 AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser);
459 AddCallback("toggleEnrollmentScreen",
460 &SigninScreenHandler::HandleToggleEnrollmentScreen);
461 AddCallback("toggleEnableDebuggingScreen",
462 &SigninScreenHandler::HandleToggleEnableDebuggingScreen);
463 AddCallback("switchToEmbeddedSignin",
464 &SigninScreenHandler::HandleSwitchToEmbeddedSignin);
465 AddCallback("toggleKioskEnableScreen",
466 &SigninScreenHandler::HandleToggleKioskEnableScreen);
467 AddCallback("createAccount", &SigninScreenHandler::HandleCreateAccount);
468 AddCallback("accountPickerReady",
469 &SigninScreenHandler::HandleAccountPickerReady);
470 AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady);
471 AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser);
472 AddCallback("openProxySettings",
473 &SigninScreenHandler::HandleOpenProxySettings);
474 AddCallback("loginVisible", &SigninScreenHandler::HandleLoginVisible);
475 AddCallback("cancelPasswordChangedFlow",
476 &SigninScreenHandler::HandleCancelPasswordChangedFlow);
477 AddCallback("cancelUserAdding", &SigninScreenHandler::HandleCancelUserAdding);
478 AddCallback("migrateUserData", &SigninScreenHandler::HandleMigrateUserData);
479 AddCallback("resyncUserData", &SigninScreenHandler::HandleResyncUserData);
480 AddCallback("loginUIStateChanged",
481 &SigninScreenHandler::HandleLoginUIStateChanged);
482 AddCallback("unlockOnLoginSuccess",
483 &SigninScreenHandler::HandleUnlockOnLoginSuccess);
484 AddCallback("showLoadingTimeoutError",
485 &SigninScreenHandler::HandleShowLoadingTimeoutError);
486 AddCallback("updateOfflineLogin",
487 &SigninScreenHandler::HandleUpdateOfflineLogin);
488 AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
489 AddCallback("getPublicSessionKeyboardLayouts",
490 &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
491 AddCallback("cancelConsumerManagementEnrollment",
492 &SigninScreenHandler::HandleCancelConsumerManagementEnrollment);
493 AddCallback("getTouchViewState",
494 &SigninScreenHandler::HandleGetTouchViewState);
496 // This message is sent by the kiosk app menu, but is handled here
497 // so we can tell the delegate to launch the app.
498 AddCallback("launchKioskApp", &SigninScreenHandler::HandleLaunchKioskApp);
501 void SigninScreenHandler::Show(const LoginScreenContext& context) {
502 CHECK(delegate_);
504 // Just initialize internal fields from context and call ShowImpl().
505 oobe_ui_ = context.oobe_ui();
507 std::string email;
508 if (is_enrolling_consumer_management_) {
509 // We don't check if the value of the owner e-mail is trusted because it is
510 // only used to pre-fill the e-mail field in Gaia sign-in page and a cached
511 // value is sufficient.
512 CrosSettings::Get()->GetString(kDeviceOwner, &email);
513 } else {
514 email = context.email();
516 gaia_screen_handler_->PopulateEmail(email);
517 ShowImpl();
518 histogram_helper_->OnScreenShow();
521 void SigninScreenHandler::SetDelegate(SigninScreenHandlerDelegate* delegate) {
522 delegate_ = delegate;
523 if (delegate_)
524 delegate_->SetWebUIHandler(this);
527 void SigninScreenHandler::SetNativeWindowDelegate(
528 NativeWindowDelegate* native_window_delegate) {
529 native_window_delegate_ = native_window_delegate;
532 void SigninScreenHandler::OnNetworkReady() {
533 VLOG(1) << "OnNetworkReady() call.";
534 DCHECK(gaia_screen_handler_);
535 gaia_screen_handler_->MaybePreloadAuthExtension();
538 void SigninScreenHandler::UpdateState(NetworkError::ErrorReason reason) {
539 UpdateStateInternal(reason, false);
542 void SigninScreenHandler::SetFocusPODCallbackForTesting(
543 base::Closure callback) {
544 test_focus_pod_callback_ = callback;
547 void SigninScreenHandler::ZeroOfflineTimeoutForTesting() {
548 zero_offline_timeout_for_test_ = true;
551 // SigninScreenHandler, private: -----------------------------------------------
553 void SigninScreenHandler::ShowImpl() {
554 if (!page_is_ready()) {
555 show_on_init_ = true;
556 return;
559 if (!ime_state_.get())
560 ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState();
562 if (!oobe_ui_observer_added_) {
563 oobe_ui_observer_added_ = true;
564 GetOobeUI()->AddObserver(this);
567 if (oobe_ui_ || is_enrolling_consumer_management_) {
568 // Shows new user sign-in for OOBE.
569 OnShowAddUser();
570 } else {
571 // Populates account picker. Animation is turned off for now until we
572 // figure out how to make it fast enough.
573 delegate_->HandleGetUsers();
575 // Reset Caps Lock state when login screen is shown.
576 input_method::InputMethodManager::Get()
577 ->GetImeKeyboard()
578 ->SetCapsLockEnabled(false);
580 base::DictionaryValue params;
581 params.SetBoolean("disableAddUser", AllWhitelistedUsersPresent());
582 UpdateUIState(UI_STATE_ACCOUNT_PICKER, &params);
586 void SigninScreenHandler::UpdateUIState(UIState ui_state,
587 base::DictionaryValue* params) {
588 switch (ui_state) {
589 case UI_STATE_GAIA_SIGNIN:
590 ui_state_ = UI_STATE_GAIA_SIGNIN;
591 ShowScreen(OobeUI::kScreenGaiaSignin, params);
592 break;
593 case UI_STATE_ACCOUNT_PICKER:
594 ui_state_ = UI_STATE_ACCOUNT_PICKER;
595 DCHECK(gaia_screen_handler_);
596 gaia_screen_handler_->CancelShowGaiaAsync();
597 ShowScreen(OobeUI::kScreenAccountPicker, params);
598 break;
599 default:
600 NOTREACHED();
601 break;
605 // TODO(antrim@): split this method into small parts.
606 // TODO(antrim@): move this logic to GaiaScreenHandler.
607 void SigninScreenHandler::UpdateStateInternal(NetworkError::ErrorReason reason,
608 bool force_update) {
609 // Do nothing once user has signed in or sign in is in progress.
610 // TODO(antrim): We will end up here when processing network state
611 // notification but no ShowSigninScreen() was called so delegate_ will be
612 // NULL. Network state processing logic does not belong here.
613 if (delegate_ &&
614 (delegate_->IsUserSigninCompleted() || delegate_->IsSigninInProgress())) {
615 return;
618 NetworkStateInformer::State state = network_state_informer_->state();
619 const std::string network_path = network_state_informer_->network_path();
620 const std::string network_name = GetNetworkName(network_path);
622 // Skip "update" notification about OFFLINE state from
623 // NetworkStateInformer if previous notification already was
624 // delayed.
625 if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) &&
626 !force_update && !update_state_closure_.IsCancelled()) {
627 return;
630 update_state_closure_.Cancel();
632 if ((state == NetworkStateInformer::OFFLINE && !force_update) ||
633 has_pending_auth_ui_) {
634 update_state_closure_.Reset(
635 base::Bind(&SigninScreenHandler::UpdateStateInternal,
636 weak_factory_.GetWeakPtr(),
637 reason,
638 true));
639 base::MessageLoop::current()->PostDelayedTask(
640 FROM_HERE,
641 update_state_closure_.callback(),
642 base::TimeDelta::FromSeconds(
643 zero_offline_timeout_for_test_ ? 0 : kOfflineTimeoutSec));
644 return;
647 // Don't show or hide error screen if we're in connecting state.
648 if (state == NetworkStateInformer::CONNECTING && !force_update) {
649 if (connecting_closure_.IsCancelled()) {
650 // First notification about CONNECTING state.
651 connecting_closure_.Reset(
652 base::Bind(&SigninScreenHandler::UpdateStateInternal,
653 weak_factory_.GetWeakPtr(),
654 reason,
655 true));
656 base::MessageLoop::current()->PostDelayedTask(
657 FROM_HERE,
658 connecting_closure_.callback(),
659 base::TimeDelta::FromSeconds(kConnectingTimeoutSec));
661 return;
663 connecting_closure_.Cancel();
665 const bool is_online = IsOnline(state, reason);
666 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
667 const bool is_gaia_loading_timeout =
668 (reason == NetworkError::ERROR_REASON_LOADING_TIMEOUT);
669 const bool is_gaia_error =
670 FrameError() != net::OK && FrameError() != net::ERR_NETWORK_CHANGED;
671 const bool is_gaia_signin = IsGaiaVisible() || IsGaiaHiddenByError();
672 const bool error_screen_should_overlay =
673 !offline_login_active_ && IsGaiaVisible();
674 const bool from_not_online_to_online_transition =
675 is_online && last_network_state_ != NetworkStateInformer::ONLINE;
676 last_network_state_ = state;
678 CallOnReturn reload_gaia(base::Bind(
679 &SigninScreenHandler::ReloadGaia, weak_factory_.GetWeakPtr(), true));
681 if (is_online || !is_behind_captive_portal)
682 network_error_model_->HideCaptivePortal();
684 // Hide offline message (if needed) and return if current screen is
685 // not a Gaia frame.
686 if (!is_gaia_signin) {
687 if (!IsSigninScreenHiddenByError())
688 HideOfflineMessage(state, reason);
689 return;
692 // Reload frame if network state is changed from {!ONLINE} -> ONLINE state.
693 if (reason == NetworkError::ERROR_REASON_NETWORK_STATE_CHANGED &&
694 from_not_online_to_online_transition) {
695 // Schedules a immediate retry.
696 LOG(WARNING) << "Retry frame load since network has been changed.";
697 reload_gaia.ScheduleCall();
700 if (reason == NetworkError::ERROR_REASON_PROXY_CONFIG_CHANGED &&
701 error_screen_should_overlay) {
702 // Schedules a immediate retry.
703 LOG(WARNING) << "Retry frameload since proxy settings has been changed.";
704 reload_gaia.ScheduleCall();
707 if (reason == NetworkError::ERROR_REASON_FRAME_ERROR &&
708 !IsProxyError(state, reason, FrameError())) {
709 LOG(WARNING) << "Retry frame load due to reason: "
710 << NetworkError::ErrorReasonString(reason);
711 reload_gaia.ScheduleCall();
714 if (is_gaia_loading_timeout) {
715 LOG(WARNING) << "Retry frame load due to loading timeout.";
716 reload_gaia.ScheduleCall();
719 if ((!is_online || is_gaia_loading_timeout || is_gaia_error) &&
720 !offline_login_active_) {
721 SetupAndShowOfflineMessage(state, reason);
722 } else {
723 HideOfflineMessage(state, reason);
727 void SigninScreenHandler::SetupAndShowOfflineMessage(
728 NetworkStateInformer::State state,
729 NetworkError::ErrorReason reason) {
730 const std::string network_path = network_state_informer_->network_path();
731 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
732 const bool is_proxy_error = IsProxyError(state, reason, FrameError());
733 const bool is_gaia_loading_timeout =
734 (reason == NetworkError::ERROR_REASON_LOADING_TIMEOUT);
736 if (is_proxy_error) {
737 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PROXY,
738 std::string());
739 } else if (is_behind_captive_portal) {
740 // Do not bother a user with obsessive captive portal showing. This
741 // check makes captive portal being shown only once: either when error
742 // screen is shown for the first time or when switching from another
743 // error screen (offline, proxy).
744 if (IsGaiaVisible() || (network_error_model_->GetErrorState() !=
745 NetworkError::ERROR_STATE_PORTAL)) {
746 network_error_model_->FixCaptivePortal();
748 const std::string network_name = GetNetworkName(network_path);
749 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PORTAL,
750 network_name);
751 } else if (is_gaia_loading_timeout) {
752 network_error_model_->SetErrorState(
753 NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT, std::string());
754 } else {
755 network_error_model_->SetErrorState(NetworkError::ERROR_STATE_OFFLINE,
756 std::string());
759 const bool guest_signin_allowed =
760 IsGuestSigninAllowed() &&
761 IsSigninScreenError(network_error_model_->GetErrorState());
762 network_error_model_->AllowGuestSignin(guest_signin_allowed);
764 const bool offline_login_allowed =
765 IsOfflineLoginAllowed() &&
766 IsSigninScreenError(network_error_model_->GetErrorState()) &&
767 network_error_model_->GetErrorState() !=
768 NetworkError::ERROR_STATE_AUTH_EXT_TIMEOUT;
769 network_error_model_->AllowOfflineLogin(offline_login_allowed);
771 if (GetCurrentScreen() != OobeUI::SCREEN_ERROR_MESSAGE) {
772 network_error_model_->SetUIState(NetworkError::UI_STATE_SIGNIN);
773 network_error_model_->SetParentScreen(OobeUI::SCREEN_GAIA_SIGNIN);
774 network_error_model_->Show();
775 histogram_helper_->OnErrorShow(network_error_model_->GetErrorState());
779 void SigninScreenHandler::HideOfflineMessage(NetworkStateInformer::State state,
780 NetworkError::ErrorReason reason) {
781 if (!IsSigninScreenHiddenByError())
782 return;
784 network_error_model_->Hide();
785 histogram_helper_->OnErrorHide();
787 // Forces a reload for Gaia screen on hiding error message.
788 if (IsGaiaVisible() || IsGaiaHiddenByError())
789 ReloadGaia(false);
792 void SigninScreenHandler::ReloadGaia(bool force_reload) {
793 gaia_screen_handler_->ReloadGaia(force_reload);
796 void SigninScreenHandler::Initialize() {
797 // If delegate_ is NULL here (e.g. WebUIScreenLocker has been destroyed),
798 // don't do anything, just return.
799 if (!delegate_)
800 return;
802 if (show_on_init_) {
803 show_on_init_ = false;
804 ShowImpl();
808 gfx::NativeWindow SigninScreenHandler::GetNativeWindow() {
809 if (native_window_delegate_)
810 return native_window_delegate_->GetNativeWindow();
811 return NULL;
814 void SigninScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
815 registry->RegisterDictionaryPref(prefs::kUsersLRUInputMethod);
818 void SigninScreenHandler::OnCurrentScreenChanged(OobeUI::Screen current_screen,
819 OobeUI::Screen new_screen) {
820 if (new_screen == OobeUI::SCREEN_ACCOUNT_PICKER) {
821 // Restore active IME state if returning to user pod row screen.
822 input_method::InputMethodManager::Get()->SetState(ime_state_);
826 void SigninScreenHandler::ClearAndEnablePassword() {
827 core_oobe_actor_->ResetSignInUI(false);
830 void SigninScreenHandler::ClearUserPodPassword() {
831 core_oobe_actor_->ClearUserPodPassword();
834 void SigninScreenHandler::RefocusCurrentPod() {
835 core_oobe_actor_->RefocusCurrentPod();
838 void SigninScreenHandler::OnUserRemoved(const std::string& username) {
839 CallJS("login.AccountPickerScreen.removeUser", username);
840 if (delegate_->GetUsers().empty())
841 OnShowAddUser();
844 void SigninScreenHandler::OnUserImageChanged(const user_manager::User& user) {
845 if (page_is_ready())
846 CallJS("login.AccountPickerScreen.updateUserImage", user.email());
849 void SigninScreenHandler::OnPreferencesChanged() {
850 // Make sure that one of the login UI is fully functional now, otherwise
851 // preferences update would be picked up next time it will be shown.
852 if (!webui_visible_) {
853 LOG(WARNING) << "Login UI is not active - postponed prefs change.";
854 preferences_changed_delayed_ = true;
855 return;
858 if (delegate_ && !delegate_->IsShowUsers()) {
859 HandleShowAddUser(NULL);
860 } else {
861 if (delegate_)
862 delegate_->HandleGetUsers();
863 UpdateUIState(UI_STATE_ACCOUNT_PICKER, NULL);
865 preferences_changed_delayed_ = false;
868 void SigninScreenHandler::ResetSigninScreenHandlerDelegate() {
869 SetDelegate(NULL);
872 void SigninScreenHandler::ShowError(int login_attempts,
873 const std::string& error_text,
874 const std::string& help_link_text,
875 HelpAppLauncher::HelpTopic help_topic_id) {
876 core_oobe_actor_->ShowSignInError(login_attempts, error_text, help_link_text,
877 help_topic_id);
880 void SigninScreenHandler::ShowErrorScreen(LoginDisplay::SigninError error_id) {
881 switch (error_id) {
882 case LoginDisplay::TPM_ERROR:
883 core_oobe_actor_->ShowTpmError();
884 break;
885 default:
886 NOTREACHED() << "Unknown sign in error";
887 break;
891 void SigninScreenHandler::ShowSigninUI(const std::string& email) {
892 core_oobe_actor_->ShowSignInUI(email);
895 void SigninScreenHandler::ShowGaiaPasswordChanged(const std::string& username) {
896 gaia_screen_handler_->PasswordChangedFor(username);
897 gaia_screen_handler_->PopulateEmail(username);
898 core_oobe_actor_->ShowSignInUI(username);
899 CallJS("login.setAuthType", username,
900 static_cast<int>(UserSelectionScreen::ONLINE_SIGN_IN),
901 base::StringValue(""));
904 void SigninScreenHandler::ShowPasswordChangedDialog(bool show_password_error) {
905 core_oobe_actor_->ShowPasswordChangedScreen(show_password_error);
908 void SigninScreenHandler::ShowSigninScreenForCreds(
909 const std::string& username,
910 const std::string& password) {
911 DCHECK(gaia_screen_handler_);
912 gaia_screen_handler_->ShowSigninScreenForCreds(username, password);
915 void SigninScreenHandler::Observe(int type,
916 const content::NotificationSource& source,
917 const content::NotificationDetails& details) {
918 switch (type) {
919 case chrome::NOTIFICATION_AUTH_NEEDED: {
920 has_pending_auth_ui_ = true;
921 break;
923 case chrome::NOTIFICATION_AUTH_SUPPLIED:
924 has_pending_auth_ui_ = false;
925 // Reload auth extension as proxy credentials are supplied.
926 if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
927 ReloadGaia(true);
928 update_state_closure_.Cancel();
929 break;
930 case chrome::NOTIFICATION_AUTH_CANCELLED: {
931 // Don't reload auth extension if proxy auth dialog was cancelled.
932 has_pending_auth_ui_ = false;
933 update_state_closure_.Cancel();
934 break;
936 default:
937 NOTREACHED() << "Unexpected notification " << type;
941 void SigninScreenHandler::OnMaximizeModeStarted() {
942 CallJS("login.AccountPickerScreen.setTouchViewState", true);
945 void SigninScreenHandler::OnMaximizeModeEnded() {
946 CallJS("login.AccountPickerScreen.setTouchViewState", false);
949 bool SigninScreenHandler::ShouldLoadGaia() const {
950 // Fetching of the extension is not started before account picker page is
951 // loaded because it can affect the loading speed.
952 // Do not load the extension for the screen locker, see crosbug.com/25018.
953 return !ScreenLocker::default_screen_locker() &&
954 is_account_picker_showing_first_time_;
957 void SigninScreenHandler::UserSettingsChanged() {
958 DCHECK(gaia_screen_handler_);
959 GaiaContext context;
960 if (delegate_)
961 context.has_users = !delegate_->GetUsers().empty();
962 gaia_screen_handler_->UpdateGaia(context);
963 UpdateAddButtonStatus();
966 void SigninScreenHandler::UpdateAddButtonStatus() {
967 CallJS("cr.ui.login.DisplayManager.updateAddUserButtonStatus",
968 AllWhitelistedUsersPresent());
971 void SigninScreenHandler::HandleAuthenticateUser(const std::string& username,
972 const std::string& password) {
973 if (!delegate_)
974 return;
975 UserContext user_context(username);
976 user_context.SetKey(Key(password));
977 delegate_->Login(user_context, SigninSpecifics());
980 void SigninScreenHandler::HandleLaunchIncognito() {
981 UserContext context(user_manager::USER_TYPE_GUEST, std::string());
982 if (delegate_)
983 delegate_->Login(context, SigninSpecifics());
986 void SigninScreenHandler::HandleShowSupervisedUserCreationScreen() {
987 if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
988 LOG(ERROR) << "Managed users not allowed.";
989 return;
991 LoginDisplayHostImpl::default_host()->
992 StartWizard(WizardController::kSupervisedUserCreationScreenName);
995 void SigninScreenHandler::HandleLaunchPublicSession(
996 const std::string& user_id,
997 const std::string& locale,
998 const std::string& input_method) {
999 if (!delegate_)
1000 return;
1002 UserContext context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user_id);
1003 context.SetPublicSessionLocale(locale),
1004 context.SetPublicSessionInputMethod(input_method);
1005 delegate_->Login(context, SigninSpecifics());
1008 void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) {
1009 if (!delegate_ || delegate_->IsShowUsers()) {
1010 NOTREACHED();
1011 return;
1013 std::string email;
1014 args->GetString(0, &email);
1016 gaia_screen_handler_->PopulateEmail(email);
1017 // Load auth extension. Parameters are: force reload, do not load extension in
1018 // background, use offline version.
1019 gaia_screen_handler_->LoadAuthExtension(true, false, true);
1020 UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL);
1023 void SigninScreenHandler::HandleShutdownSystem() {
1024 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
1027 void SigninScreenHandler::HandleLoadWallpaper(const std::string& email) {
1028 if (delegate_)
1029 delegate_->LoadWallpaper(email);
1032 void SigninScreenHandler::HandleRebootSystem() {
1033 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
1036 void SigninScreenHandler::HandleRemoveUser(const std::string& email) {
1037 if (!delegate_)
1038 return;
1039 delegate_->RemoveUser(email);
1040 UpdateAddButtonStatus();
1043 void SigninScreenHandler::HandleShowAddUser(const base::ListValue* args) {
1044 TRACE_EVENT_ASYNC_STEP_INTO0("ui",
1045 "ShowLoginWebUI",
1046 LoginDisplayHostImpl::kShowLoginWebUIid,
1047 "ShowAddUser");
1048 std::string email;
1049 // |args| can be null if it's OOBE.
1050 if (args)
1051 args->GetString(0, &email);
1052 gaia_screen_handler_->PopulateEmail(email);
1053 OnShowAddUser();
1056 void SigninScreenHandler::HandleToggleEnrollmentScreen() {
1057 if (delegate_)
1058 delegate_->ShowEnterpriseEnrollmentScreen();
1061 void SigninScreenHandler::HandleToggleEnableDebuggingScreen() {
1062 if (delegate_)
1063 delegate_->ShowEnableDebuggingScreen();
1066 void SigninScreenHandler::HandleToggleKioskEnableScreen() {
1067 policy::BrowserPolicyConnectorChromeOS* connector =
1068 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1069 if (delegate_ && !connector->IsEnterpriseManaged() &&
1070 LoginDisplayHostImpl::default_host()) {
1071 delegate_->ShowKioskEnableScreen();
1075 void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() {
1076 policy::BrowserPolicyConnectorChromeOS* connector =
1077 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1078 if (delegate_ && !connector->IsEnterpriseManaged())
1079 delegate_->ShowKioskAutolaunchScreen();
1082 void SigninScreenHandler::LoadUsers(const base::ListValue& users_list,
1083 bool showGuest) {
1084 CallJS("login.AccountPickerScreen.loadUsers",
1085 users_list,
1086 delegate_->IsShowGuest());
1089 void SigninScreenHandler::HandleAccountPickerReady() {
1090 VLOG(0) << "Login WebUI >> AccountPickerReady";
1092 if (delegate_ && !ScreenLocker::default_screen_locker() &&
1093 !chromeos::IsMachineHWIDCorrect() &&
1094 !oobe_ui_) {
1095 delegate_->ShowWrongHWIDScreen();
1096 return;
1099 PrefService* prefs = g_browser_process->local_state();
1100 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
1101 if (core_oobe_actor_)
1102 core_oobe_actor_->ShowDeviceResetScreen();
1104 return;
1105 } else if (prefs->GetBoolean(prefs::kDebuggingFeaturesRequested)) {
1106 if (core_oobe_actor_)
1107 core_oobe_actor_->ShowEnableDebuggingScreen();
1109 return;
1112 is_account_picker_showing_first_time_ = true;
1114 if (delegate_)
1115 delegate_->OnSigninScreenReady();
1118 void SigninScreenHandler::HandleWallpaperReady() {
1119 if (ScreenLocker::default_screen_locker()) {
1120 ScreenLocker::default_screen_locker()->delegate()->
1121 OnLockBackgroundDisplayed();
1125 void SigninScreenHandler::HandleSignOutUser() {
1126 if (delegate_)
1127 delegate_->Signout();
1130 void SigninScreenHandler::HandleCreateAccount() {
1131 if (delegate_)
1132 delegate_->CreateAccount();
1135 void SigninScreenHandler::HandleOpenProxySettings() {
1136 LoginDisplayHostImpl::default_host()->OpenProxySettings();
1139 void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
1140 VLOG(1) << "Login WebUI >> loginVisible, src: " << source << ", "
1141 << "webui_visible_: " << webui_visible_;
1142 if (!webui_visible_) {
1143 // There might be multiple messages from OOBE UI so send notifications after
1144 // the first one only.
1145 content::NotificationService::current()->Notify(
1146 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
1147 content::NotificationService::AllSources(),
1148 content::NotificationService::NoDetails());
1149 TRACE_EVENT_ASYNC_END0(
1150 "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid);
1152 webui_visible_ = true;
1153 if (preferences_changed_delayed_)
1154 OnPreferencesChanged();
1157 void SigninScreenHandler::HandleCancelPasswordChangedFlow() {
1158 gaia_screen_handler_->StartClearingCookies(
1159 base::Bind(&SigninScreenHandler::CancelPasswordChangedFlowInternal,
1160 weak_factory_.GetWeakPtr()));
1163 void SigninScreenHandler::HandleCancelUserAdding() {
1164 if (delegate_)
1165 delegate_->CancelUserAdding();
1168 void SigninScreenHandler::HandleMigrateUserData(
1169 const std::string& old_password) {
1170 if (delegate_)
1171 delegate_->MigrateUserData(old_password);
1174 void SigninScreenHandler::HandleResyncUserData() {
1175 if (delegate_)
1176 delegate_->ResyncUserData();
1179 void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source,
1180 bool new_value) {
1181 VLOG(0) << "Login WebUI >> active: " << new_value << ", "
1182 << "source: " << source;
1184 if (source == "gaia-signin" && !new_value)
1185 gaia_screen_handler_->CancelEmbeddedSignin();
1187 if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() &&
1188 KioskAppManager::Get()->IsAutoLaunchRequested()) {
1189 VLOG(0) << "Showing auto-launch warning";
1190 // On slow devices, the wallpaper animation is not shown initially, so we
1191 // must explicitly load the wallpaper. This is also the case for the
1192 // account-picker and gaia-signin UI states.
1193 delegate_->LoadSigninWallpaper();
1194 HandleToggleKioskAutolaunchScreen();
1195 return;
1198 if (source == kSourceGaiaSignin) {
1199 ui_state_ = UI_STATE_GAIA_SIGNIN;
1200 } else if (source == kSourceAccountPicker) {
1201 ui_state_ = UI_STATE_ACCOUNT_PICKER;
1202 } else {
1203 NOTREACHED();
1204 return;
1208 void SigninScreenHandler::HandleUnlockOnLoginSuccess() {
1209 DCHECK(user_manager::UserManager::Get()->IsUserLoggedIn());
1210 if (ScreenLocker::default_screen_locker())
1211 ScreenLocker::default_screen_locker()->UnlockOnLoginSuccess();
1214 void SigninScreenHandler::HandleShowLoadingTimeoutError() {
1215 UpdateState(NetworkError::ERROR_REASON_LOADING_TIMEOUT);
1218 void SigninScreenHandler::HandleUpdateOfflineLogin(bool offline_login_active) {
1219 offline_login_active_ = offline_login_active;
1222 void SigninScreenHandler::HandleFocusPod(const std::string& user_id) {
1223 SetUserInputMethod(user_id, ime_state_.get());
1224 WallpaperManager::Get()->SetUserWallpaperDelayed(user_id);
1225 ScreenlockBridge::Get()->SetFocusedUser(user_id);
1226 if (!test_focus_pod_callback_.is_null())
1227 test_focus_pod_callback_.Run();
1230 void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
1231 const std::string& user_id,
1232 const std::string& locale) {
1233 GetKeyboardLayoutsForLocale(
1234 base::Bind(&SigninScreenHandler::SendPublicSessionKeyboardLayouts,
1235 weak_factory_.GetWeakPtr(),
1236 user_id,
1237 locale),
1238 locale);
1241 void SigninScreenHandler::SendPublicSessionKeyboardLayouts(
1242 const std::string& user_id,
1243 const std::string& locale,
1244 scoped_ptr<base::ListValue> keyboard_layouts) {
1245 CallJS("login.AccountPickerScreen.setPublicSessionKeyboardLayouts",
1246 user_id,
1247 locale,
1248 *keyboard_layouts);
1251 void SigninScreenHandler::HandleLaunchKioskApp(const std::string& app_id,
1252 bool diagnostic_mode) {
1253 UserContext context(user_manager::USER_TYPE_KIOSK_APP, app_id);
1254 SigninSpecifics specifics;
1255 specifics.kiosk_diagnostic_mode = diagnostic_mode;
1256 if (delegate_)
1257 delegate_->Login(context, specifics);
1260 void SigninScreenHandler::HandleCancelConsumerManagementEnrollment() {
1261 policy::ConsumerManagementService* consumer_management =
1262 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
1263 GetConsumerManagementService();
1264 CHECK(consumer_management);
1265 consumer_management->SetStage(
1266 policy::ConsumerManagementStage::EnrollmentCanceled());
1267 is_enrolling_consumer_management_ = false;
1268 ShowImpl();
1271 void SigninScreenHandler::HandleGetTouchViewState() {
1272 if (max_mode_delegate_) {
1273 CallJS("login.AccountPickerScreen.setTouchViewState",
1274 max_mode_delegate_->IsMaximizeModeEnabled());
1278 void SigninScreenHandler::HandleSwitchToEmbeddedSignin() {
1279 gaia_screen_handler_->SwitchToEmbeddedSignin();
1282 bool SigninScreenHandler::AllWhitelistedUsersPresent() {
1283 CrosSettings* cros_settings = CrosSettings::Get();
1284 bool allow_new_user = false;
1285 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
1286 if (allow_new_user)
1287 return false;
1288 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1289 const user_manager::UserList& users = user_manager->GetUsers();
1290 if (!delegate_ || users.size() > kMaxUsers) {
1291 return false;
1293 const base::ListValue* whitelist = NULL;
1294 if (!cros_settings->GetList(kAccountsPrefUsers, &whitelist) || !whitelist)
1295 return false;
1296 for (size_t i = 0; i < whitelist->GetSize(); ++i) {
1297 std::string whitelisted_user;
1298 // NB: Wildcards in the whitelist are also detected as not present here.
1299 if (!whitelist->GetString(i, &whitelisted_user) ||
1300 !user_manager->IsKnownUser(whitelisted_user)) {
1301 return false;
1304 return true;
1307 void SigninScreenHandler::CancelPasswordChangedFlowInternal() {
1308 if (delegate_) {
1309 ShowImpl();
1310 delegate_->CancelPasswordChangedFlow();
1314 OobeUI* SigninScreenHandler::GetOobeUI() const {
1315 return static_cast<OobeUI*>(web_ui()->GetController());
1318 OobeUI::Screen SigninScreenHandler::GetCurrentScreen() const {
1319 OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
1320 OobeUI* oobe_ui = GetOobeUI();
1321 if (oobe_ui)
1322 screen = oobe_ui->current_screen();
1323 return screen;
1326 bool SigninScreenHandler::IsGaiaVisible() const {
1327 return IsSigninScreen(GetCurrentScreen()) &&
1328 ui_state_ == UI_STATE_GAIA_SIGNIN;
1331 bool SigninScreenHandler::IsGaiaHiddenByError() const {
1332 return IsSigninScreenHiddenByError() &&
1333 ui_state_ == UI_STATE_GAIA_SIGNIN;
1336 bool SigninScreenHandler::IsSigninScreenHiddenByError() const {
1337 return (GetCurrentScreen() == OobeUI::SCREEN_ERROR_MESSAGE) &&
1338 (IsSigninScreen(network_error_model_->GetParentScreen()));
1341 bool SigninScreenHandler::IsGuestSigninAllowed() const {
1342 CrosSettings* cros_settings = CrosSettings::Get();
1343 if (!cros_settings)
1344 return false;
1345 bool allow_guest;
1346 cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
1347 return allow_guest;
1350 bool SigninScreenHandler::IsOfflineLoginAllowed() const {
1351 CrosSettings* cros_settings = CrosSettings::Get();
1352 if (!cros_settings)
1353 return false;
1355 // Offline login is allowed only when user pods are hidden.
1356 bool show_pods;
1357 cros_settings->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_pods);
1358 return !show_pods;
1361 void SigninScreenHandler::OnShowAddUser() {
1362 is_account_picker_showing_first_time_ = false;
1363 DCHECK(gaia_screen_handler_);
1364 gaia_screen_handler_->ShowGaiaAsync(is_enrolling_consumer_management_);
1367 net::Error SigninScreenHandler::FrameError() const {
1368 DCHECK(gaia_screen_handler_);
1369 return gaia_screen_handler_->frame_error();
1372 void SigninScreenHandler::OnCapsLockChanged(bool enabled) {
1373 caps_lock_enabled_ = enabled;
1374 if (page_is_ready())
1375 CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_);
1378 } // namespace chromeos