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"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/debug/trace_event.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 "chrome/browser/browser_process.h"
25 #include "chrome/browser/browser_process_platform_part_chromeos.h"
26 #include "chrome/browser/browser_shutdown.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
29 #include "chrome/browser/chromeos/boot_times_loader.h"
30 #include "chrome/browser/chromeos/input_method/input_method_util.h"
31 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.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/ui/login_display_host.h"
36 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
37 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
38 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
39 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
40 #include "chrome/browser/chromeos/login/wizard_controller.h"
41 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
42 #include "chrome/browser/chromeos/policy/consumer_management_service.h"
43 #include "chrome/browser/chromeos/policy/device_local_account.h"
44 #include "chrome/browser/chromeos/profiles/profile_helper.h"
45 #include "chrome/browser/chromeos/settings/cros_settings.h"
46 #include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
47 #include "chrome/browser/io_thread.h"
48 #include "chrome/browser/profiles/profile.h"
49 #include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h"
50 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
51 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
52 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
53 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
54 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
55 #include "chrome/common/pref_names.h"
56 #include "chrome/common/url_constants.h"
57 #include "chromeos/dbus/dbus_thread_manager.h"
58 #include "chromeos/dbus/power_manager_client.h"
59 #include "chromeos/ime/ime_keyboard.h"
60 #include "chromeos/ime/input_method_descriptor.h"
61 #include "chromeos/ime/input_method_manager.h"
62 #include "chromeos/login/auth/key.h"
63 #include "chromeos/login/auth/user_context.h"
64 #include "chromeos/network/network_state.h"
65 #include "chromeos/network/network_state_handler.h"
66 #include "chromeos/network/portal_detector/network_portal_detector.h"
67 #include "components/user_manager/user.h"
68 #include "components/user_manager/user_manager.h"
69 #include "components/user_manager/user_type.h"
70 #include "content/public/browser/render_frame_host.h"
71 #include "content/public/browser/web_contents.h"
72 #include "google_apis/gaia/gaia_auth_util.h"
73 #include "grit/chromium_strings.h"
74 #include "grit/generated_resources.h"
75 #include "net/url_request/url_request_context_getter.h"
76 #include "third_party/cros_system_api/dbus/service_constants.h"
77 #include "ui/base/webui/web_ui_util.h"
80 #include "ash/shell.h"
81 #include "ash/wm/lock_state_controller.h"
86 // Max number of users to show.
87 const size_t kMaxUsers = 18;
89 // Timeout to delay first notification about offline state for a
91 const int kOfflineTimeoutSec = 5;
93 // Timeout used to prevent infinite connecting to a flaky network.
94 const int kConnectingTimeoutSec = 60;
96 // Type of the login screen UI that is currently presented to user.
97 const char kSourceGaiaSignin[] = "gaia-signin";
98 const char kSourceAccountPicker[] = "account-picker";
100 static bool Contains(const std::vector<std::string>& container,
101 const std::string& value) {
102 return std::find(container.begin(), container.end(), value) !=
108 explicit CallOnReturn(const base::Closure& callback)
109 : callback_(callback), call_scheduled_(false) {}
112 if (call_scheduled_ && !callback_.is_null())
116 void ScheduleCall() { call_scheduled_ = true; }
119 base::Closure callback_;
120 bool call_scheduled_;
122 DISALLOW_COPY_AND_ASSIGN(CallOnReturn);
131 bool IsOnline(NetworkStateInformer::State state,
132 ErrorScreenActor::ErrorReason reason) {
133 return state == NetworkStateInformer::ONLINE &&
134 reason != ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED &&
135 reason != ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT;
138 bool IsBehindCaptivePortal(NetworkStateInformer::State state,
139 ErrorScreenActor::ErrorReason reason) {
140 return state == NetworkStateInformer::CAPTIVE_PORTAL ||
141 reason == ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED;
144 bool IsProxyError(NetworkStateInformer::State state,
145 ErrorScreenActor::ErrorReason reason,
146 net::Error frame_error) {
147 return state == NetworkStateInformer::PROXY_AUTH_REQUIRED ||
148 reason == ErrorScreenActor::ERROR_REASON_PROXY_AUTH_CANCELLED ||
149 reason == ErrorScreenActor::ERROR_REASON_PROXY_CONNECTION_FAILED ||
150 (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
151 (frame_error == net::ERR_PROXY_CONNECTION_FAILED ||
152 frame_error == net::ERR_TUNNEL_CONNECTION_FAILED));
155 bool IsSigninScreen(const OobeUI::Screen screen) {
156 return screen == OobeUI::SCREEN_GAIA_SIGNIN ||
157 screen == OobeUI::SCREEN_ACCOUNT_PICKER;
160 bool IsSigninScreenError(ErrorScreen::ErrorState error_state) {
161 return error_state == ErrorScreen::ERROR_STATE_PORTAL ||
162 error_state == ErrorScreen::ERROR_STATE_OFFLINE ||
163 error_state == ErrorScreen::ERROR_STATE_PROXY ||
164 error_state == ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT;
167 // Returns network name by service path.
168 std::string GetNetworkName(const std::string& service_path) {
169 const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
170 GetNetworkState(service_path);
172 return std::string();
173 return network->name();
176 static bool SetUserInputMethodImpl(
177 const std::string& username,
178 chromeos::input_method::InputMethodManager* manager) {
179 PrefService* const local_state = g_browser_process->local_state();
181 const base::DictionaryValue* users_lru_input_methods =
182 local_state->GetDictionary(prefs::kUsersLRUInputMethod);
184 if (users_lru_input_methods == NULL) {
185 DLOG(WARNING) << "SetUserInputMethod('" << username
186 << "'): no kUsersLRUInputMethod";
190 std::string input_method;
192 if (!users_lru_input_methods->GetStringWithoutPathExpansion(username,
194 DVLOG(0) << "SetUserInputMethod('" << username
195 << "'): no input method for this user";
199 if (input_method.empty())
202 if (!manager->IsLoginKeyboard(input_method)) {
203 LOG(WARNING) << "SetUserInputMethod('" << username
204 << "'): stored user LRU input method '" << input_method
205 << "' is no longer Full Latin Keyboard Language"
206 << " (entry dropped). Use hardware default instead.";
208 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
210 base::DictionaryValue* const users_lru_input_methods = updater.Get();
211 if (users_lru_input_methods != NULL) {
212 users_lru_input_methods->SetStringWithoutPathExpansion(username, "");
217 if (!Contains(manager->GetActiveInputMethodIds(), input_method)) {
218 if (!manager->EnableInputMethod(input_method)) {
219 DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username
220 << "'): user input method '" << input_method
221 << "' is not enabled and enabling failed (ignored!).";
224 manager->ChangeInputMethod(input_method);
231 // LoginScreenContext implementation ------------------------------------------
233 LoginScreenContext::LoginScreenContext() {
237 LoginScreenContext::LoginScreenContext(const base::ListValue* args) {
240 if (!args || args->GetSize() == 0)
243 if (args->GetString(0, &email))
247 void LoginScreenContext::Init() {
251 // SigninScreenHandler implementation ------------------------------------------
253 SigninScreenHandler::SigninScreenHandler(
254 const scoped_refptr<NetworkStateInformer>& network_state_informer,
255 ErrorScreenActor* error_screen_actor,
256 CoreOobeActor* core_oobe_actor,
257 GaiaScreenHandler* gaia_screen_handler)
258 : ui_state_(UI_STATE_UNKNOWN),
260 native_window_delegate_(NULL),
261 show_on_init_(false),
263 is_account_picker_showing_first_time_(false),
264 network_state_informer_(network_state_informer),
265 webui_visible_(false),
266 preferences_changed_delayed_(false),
267 error_screen_actor_(error_screen_actor),
268 core_oobe_actor_(core_oobe_actor),
269 is_first_update_state_call_(true),
270 offline_login_active_(false),
271 last_network_state_(NetworkStateInformer::UNKNOWN),
272 has_pending_auth_ui_(false),
273 caps_lock_enabled_(chromeos::input_method::InputMethodManager::Get()
275 ->CapsLockIsEnabled()),
276 gaia_screen_handler_(gaia_screen_handler),
277 weak_factory_(this) {
278 DCHECK(network_state_informer_.get());
279 DCHECK(error_screen_actor_);
280 DCHECK(core_oobe_actor_);
281 DCHECK(gaia_screen_handler_);
282 gaia_screen_handler_->SetSigninScreenHandler(this);
283 network_state_informer_->AddObserver(this);
286 chrome::NOTIFICATION_AUTH_NEEDED,
287 content::NotificationService::AllSources());
289 chrome::NOTIFICATION_AUTH_SUPPLIED,
290 content::NotificationService::AllSources());
292 chrome::NOTIFICATION_AUTH_CANCELLED,
293 content::NotificationService::AllSources());
295 chromeos::input_method::ImeKeyboard* keyboard =
296 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
298 keyboard->AddObserver(this);
300 policy::ConsumerManagementService* consumer_management =
301 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
302 GetConsumerManagementService();
303 is_enrolling_consumer_management_ =
304 consumer_management &&
305 consumer_management->GetEnrollmentState() ==
306 policy::ConsumerManagementService::ENROLLMENT_ENROLLING;
309 SigninScreenHandler::~SigninScreenHandler() {
310 chromeos::input_method::ImeKeyboard* keyboard =
311 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
313 keyboard->RemoveObserver(this);
314 weak_factory_.InvalidateWeakPtrs();
316 delegate_->SetWebUIHandler(NULL);
317 network_state_informer_->RemoveObserver(this);
318 ScreenlockBridge::Get()->SetLockHandler(NULL);
321 void SigninScreenHandler::DeclareLocalizedValues(
322 LocalizedValuesBuilder* builder) {
323 builder->Add("passwordHint", IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT);
324 builder->Add("podMenuButtonAccessibleName",
325 IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME);
326 builder->Add("podMenuRemoveItemAccessibleName",
327 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME);
328 builder->Add("passwordFieldAccessibleName",
329 IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME);
330 builder->Add("signedIn", IDS_SCREEN_LOCK_ACTIVE_USER);
331 builder->Add("signinButton", IDS_LOGIN_BUTTON);
332 builder->Add("launchAppButton", IDS_LAUNCH_APP_BUTTON);
333 builder->Add("shutDown", IDS_SHUTDOWN_BUTTON);
334 builder->Add("addUser", IDS_ADD_USER_BUTTON);
335 builder->Add("browseAsGuest", IDS_GO_INCOGNITO_BUTTON);
336 builder->Add("cancel", IDS_CANCEL);
337 builder->Add("signOutUser", IDS_SCREEN_LOCK_SIGN_OUT);
338 builder->Add("offlineLogin", IDS_OFFLINE_LOGIN_HTML);
339 builder->Add("ownerUserPattern", IDS_LOGIN_POD_OWNER_USER);
340 builder->Add("removeUser", IDS_LOGIN_POD_REMOVE_USER);
341 builder->Add("errorTpmFailureTitle", IDS_LOGIN_ERROR_TPM_FAILURE_TITLE);
342 builder->Add("errorTpmFailureReboot", IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT);
343 builder->Add("errorTpmFailureRebootButton",
344 IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT_BUTTON);
346 policy::BrowserPolicyConnectorChromeOS* connector =
347 g_browser_process->platform_part()->browser_policy_connector_chromeos();
348 builder->Add("disabledAddUserTooltip",
349 connector->IsEnterpriseManaged()
350 ? IDS_DISABLED_ADD_USER_TOOLTIP_ENTERPRISE
351 : IDS_DISABLED_ADD_USER_TOOLTIP);
353 builder->Add("supervisedUserExpiredTokenWarning",
354 IDS_SUPERVISED_USER_EXPIRED_TOKEN_WARNING);
355 builder->Add("signinBannerText", IDS_LOGIN_USER_ADDING_BANNER);
357 // Multi-profiles related strings.
358 builder->Add("multiProfilesRestrictedPolicyTitle",
359 IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE);
360 builder->Add("multiProfilesNotAllowedPolicyMsg",
361 IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG);
362 builder->Add("multiProfilesPrimaryOnlyPolicyMsg",
363 IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG);
364 builder->Add("multiProfilesOwnerPrimaryOnlyMsg",
365 IDS_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG);
367 // Strings used by password changed dialog.
368 builder->Add("passwordChangedTitle", IDS_LOGIN_PASSWORD_CHANGED_TITLE);
369 builder->Add("passwordChangedDesc", IDS_LOGIN_PASSWORD_CHANGED_DESC);
370 builder->AddF("passwordChangedMoreInfo",
371 IDS_LOGIN_PASSWORD_CHANGED_MORE_INFO,
372 IDS_SHORT_PRODUCT_OS_NAME);
374 builder->Add("oldPasswordHint", IDS_LOGIN_PASSWORD_CHANGED_OLD_PASSWORD_HINT);
375 builder->Add("oldPasswordIncorrect",
376 IDS_LOGIN_PASSWORD_CHANGED_INCORRECT_OLD_PASSWORD);
377 builder->Add("passwordChangedCantRemember",
378 IDS_LOGIN_PASSWORD_CHANGED_CANT_REMEMBER);
379 builder->Add("passwordChangedBackButton",
380 IDS_LOGIN_PASSWORD_CHANGED_BACK_BUTTON);
381 builder->Add("passwordChangedsOkButton", IDS_OK);
382 builder->Add("passwordChangedProceedAnyway",
383 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY);
384 builder->Add("proceedAnywayButton",
385 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY_BUTTON);
386 builder->Add("publicAccountInfoFormat", IDS_LOGIN_PUBLIC_ACCOUNT_INFO_FORMAT);
387 builder->Add("publicAccountReminder",
388 IDS_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER);
389 builder->Add("publicSessionLanguageAndInput",
390 IDS_LOGIN_PUBLIC_SESSION_LANGUAGE_AND_INPUT);
391 builder->Add("publicAccountEnter", IDS_LOGIN_PUBLIC_ACCOUNT_ENTER);
392 builder->Add("publicAccountEnterAccessibleName",
393 IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME);
394 builder->Add("publicSessionSelectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
395 builder->Add("publicSessionSelectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
396 builder->Add("removeUserWarningText",
398 builder->AddF("removeSupervisedUserWarningText",
399 IDS_LOGIN_POD_SUPERVISED_USER_REMOVE_WARNING,
400 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL));
401 builder->Add("removeUserWarningButtonTitle",
402 IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON);
404 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE);
406 builder->Add("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE);
407 builder->Add("confirmPasswordLabel", IDS_LOGIN_CONFIRM_PASSWORD_LABEL);
408 builder->Add("confirmPasswordConfirmButton",
409 IDS_LOGIN_CONFIRM_PASSWORD_CONFIRM_BUTTON);
410 builder->Add("confirmPasswordText", IDS_LOGIN_CONFIRM_PASSWORD_TEXT);
411 builder->Add("confirmPasswordErrorText",
412 IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT);
414 builder->Add("fatalEnrollmentError",
415 IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR);
416 builder->Add("insecureURLEnrollmentError",
417 IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR);
419 if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled())
420 builder->Add("demoLoginMessage", IDS_KIOSK_MODE_LOGIN_MESSAGE);
423 void SigninScreenHandler::Show(const LoginScreenContext& context) {
426 // Just initialize internal fields from context and call ShowImpl().
427 oobe_ui_ = context.oobe_ui();
430 if (is_enrolling_consumer_management_) {
431 // We don't check if the value of the owner e-mail is trusted because it is
432 // only used to pre-fill the e-mail field in Gaia sign-in page and a cached
433 // value is sufficient.
434 CrosSettings::Get()->GetString(kDeviceOwner, &email);
436 email = context.email();
438 gaia_screen_handler_->PopulateEmail(email);
442 void SigninScreenHandler::ShowRetailModeLoginSpinner() {
443 CallJS("showLoginSpinner");
446 void SigninScreenHandler::SetDelegate(SigninScreenHandlerDelegate* delegate) {
447 delegate_ = delegate;
449 delegate_->SetWebUIHandler(this);
451 auto_enrollment_progress_subscription_.reset();
454 void SigninScreenHandler::SetNativeWindowDelegate(
455 NativeWindowDelegate* native_window_delegate) {
456 native_window_delegate_ = native_window_delegate;
459 void SigninScreenHandler::OnNetworkReady() {
460 VLOG(1) << "OnNetworkReady() call.";
461 DCHECK(gaia_screen_handler_);
462 gaia_screen_handler_->MaybePreloadAuthExtension();
465 void SigninScreenHandler::UpdateState(ErrorScreenActor::ErrorReason reason) {
466 UpdateStateInternal(reason, false);
469 // SigninScreenHandler, private: -----------------------------------------------
471 void SigninScreenHandler::ShowImpl() {
472 if (!page_is_ready()) {
473 show_on_init_ = true;
477 if (oobe_ui_ || is_enrolling_consumer_management_) {
478 // Shows new user sign-in for OOBE.
481 // Populates account picker. Animation is turned off for now until we
482 // figure out how to make it fast enough.
483 delegate_->HandleGetUsers();
485 // Reset Caps Lock state when login screen is shown.
486 input_method::InputMethodManager::Get()
488 ->SetCapsLockEnabled(false);
490 base::DictionaryValue params;
491 params.SetBoolean("disableAddUser", AllWhitelistedUsersPresent());
492 UpdateUIState(UI_STATE_ACCOUNT_PICKER, ¶ms);
496 void SigninScreenHandler::UpdateUIState(UIState ui_state,
497 base::DictionaryValue* params) {
499 case UI_STATE_GAIA_SIGNIN:
500 ui_state_ = UI_STATE_GAIA_SIGNIN;
501 ShowScreen(OobeUI::kScreenGaiaSignin, params);
503 case UI_STATE_ACCOUNT_PICKER:
504 ui_state_ = UI_STATE_ACCOUNT_PICKER;
505 ShowScreen(OobeUI::kScreenAccountPicker, params);
513 // TODO(ygorshenin@): split this method into small parts.
514 // TODO(ygorshenin@): move this logic to GaiaScreenHandler.
515 void SigninScreenHandler::UpdateStateInternal(
516 ErrorScreenActor::ErrorReason reason,
518 // Do nothing once user has signed in or sign in is in progress.
519 // TODO(ygorshenin): We will end up here when processing network state
520 // notification but no ShowSigninScreen() was called so delegate_ will be
521 // NULL. Network state processing logic does not belong here.
523 (delegate_->IsUserSigninCompleted() || delegate_->IsSigninInProgress())) {
527 NetworkStateInformer::State state = network_state_informer_->state();
528 const std::string network_path = network_state_informer_->network_path();
529 const std::string network_name = GetNetworkName(network_path);
531 // Skip "update" notification about OFFLINE state from
532 // NetworkStateInformer if previous notification already was
534 if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) &&
535 !force_update && !update_state_closure_.IsCancelled()) {
539 update_state_closure_.Cancel();
541 if ((state == NetworkStateInformer::OFFLINE && !force_update) ||
542 has_pending_auth_ui_) {
543 update_state_closure_.Reset(
544 base::Bind(&SigninScreenHandler::UpdateStateInternal,
545 weak_factory_.GetWeakPtr(),
548 base::MessageLoop::current()->PostDelayedTask(
550 update_state_closure_.callback(),
551 base::TimeDelta::FromSeconds(kOfflineTimeoutSec));
555 // Don't show or hide error screen if we're in connecting state.
556 if (state == NetworkStateInformer::CONNECTING && !force_update) {
557 if (connecting_closure_.IsCancelled()) {
558 // First notification about CONNECTING state.
559 connecting_closure_.Reset(
560 base::Bind(&SigninScreenHandler::UpdateStateInternal,
561 weak_factory_.GetWeakPtr(),
564 base::MessageLoop::current()->PostDelayedTask(
566 connecting_closure_.callback(),
567 base::TimeDelta::FromSeconds(kConnectingTimeoutSec));
571 connecting_closure_.Cancel();
573 const bool is_online = IsOnline(state, reason);
574 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
575 const bool is_gaia_loading_timeout =
576 (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
577 const bool is_gaia_error =
578 FrameError() != net::OK && FrameError() != net::ERR_NETWORK_CHANGED;
579 const bool is_gaia_signin = IsGaiaVisible() || IsGaiaHiddenByError();
580 const bool error_screen_should_overlay =
581 !offline_login_active_ && IsGaiaVisible();
582 const bool from_not_online_to_online_transition =
583 is_online && last_network_state_ != NetworkStateInformer::ONLINE;
584 last_network_state_ = state;
586 CallOnReturn reload_gaia(base::Bind(
587 &SigninScreenHandler::ReloadGaia, weak_factory_.GetWeakPtr(), true));
589 if (is_online || !is_behind_captive_portal)
590 error_screen_actor_->HideCaptivePortal();
592 // Hide offline message (if needed) and return if current screen is
594 if (!is_gaia_signin) {
595 if (!IsSigninScreenHiddenByError())
596 HideOfflineMessage(state, reason);
600 // Reload frame if network state is changed from {!ONLINE} -> ONLINE state.
601 if (reason == ErrorScreenActor::ERROR_REASON_NETWORK_STATE_CHANGED &&
602 from_not_online_to_online_transition) {
603 // Schedules a immediate retry.
604 LOG(WARNING) << "Retry frame load since network has been changed.";
605 reload_gaia.ScheduleCall();
608 if (reason == ErrorScreenActor::ERROR_REASON_PROXY_CONFIG_CHANGED &&
609 error_screen_should_overlay) {
610 // Schedules a immediate retry.
611 LOG(WARNING) << "Retry frameload since proxy settings has been changed.";
612 reload_gaia.ScheduleCall();
615 if (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
616 !IsProxyError(state, reason, FrameError())) {
617 LOG(WARNING) << "Retry frame load due to reason: "
618 << ErrorScreenActor::ErrorReasonString(reason);
619 reload_gaia.ScheduleCall();
622 if (is_gaia_loading_timeout) {
623 LOG(WARNING) << "Retry frame load due to loading timeout.";
624 reload_gaia.ScheduleCall();
627 if ((!is_online || is_gaia_loading_timeout || is_gaia_error) &&
628 !offline_login_active_) {
629 SetupAndShowOfflineMessage(state, reason);
631 HideOfflineMessage(state, reason);
635 void SigninScreenHandler::SetupAndShowOfflineMessage(
636 NetworkStateInformer:: State state,
637 ErrorScreenActor::ErrorReason reason) {
638 const std::string network_path = network_state_informer_->network_path();
639 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
640 const bool is_proxy_error = IsProxyError(state, reason, FrameError());
641 const bool is_gaia_loading_timeout =
642 (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
644 if (is_proxy_error) {
645 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PROXY,
647 } else if (is_behind_captive_portal) {
648 // Do not bother a user with obsessive captive portal showing. This
649 // check makes captive portal being shown only once: either when error
650 // screen is shown for the first time or when switching from another
651 // error screen (offline, proxy).
652 if (IsGaiaVisible() ||
653 (error_screen_actor_->error_state() !=
654 ErrorScreen::ERROR_STATE_PORTAL)) {
655 error_screen_actor_->FixCaptivePortal();
657 const std::string network_name = GetNetworkName(network_path);
658 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PORTAL,
660 } else if (is_gaia_loading_timeout) {
661 error_screen_actor_->SetErrorState(
662 ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT, std::string());
664 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE,
668 const bool guest_signin_allowed = IsGuestSigninAllowed() &&
669 IsSigninScreenError(error_screen_actor_->error_state());
670 error_screen_actor_->AllowGuestSignin(guest_signin_allowed);
672 const bool offline_login_allowed = IsOfflineLoginAllowed() &&
673 IsSigninScreenError(error_screen_actor_->error_state()) &&
674 error_screen_actor_->error_state() !=
675 ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT;
676 error_screen_actor_->AllowOfflineLogin(offline_login_allowed);
678 if (GetCurrentScreen() != OobeUI::SCREEN_ERROR_MESSAGE) {
679 base::DictionaryValue params;
680 const std::string network_type = network_state_informer_->network_type();
681 params.SetString("lastNetworkType", network_type);
682 error_screen_actor_->SetUIState(ErrorScreen::UI_STATE_SIGNIN);
683 error_screen_actor_->Show(OobeUI::SCREEN_GAIA_SIGNIN, ¶ms);
687 void SigninScreenHandler::HideOfflineMessage(
688 NetworkStateInformer::State state,
689 ErrorScreenActor::ErrorReason reason) {
690 if (!IsSigninScreenHiddenByError())
693 error_screen_actor_->Hide();
695 // Forces a reload for Gaia screen on hiding error message.
696 if (IsGaiaVisible() || IsGaiaHiddenByError())
700 void SigninScreenHandler::ReloadGaia(bool force_reload) {
701 gaia_screen_handler_->ReloadGaia(force_reload);
704 void SigninScreenHandler::Initialize() {
705 // If delegate_ is NULL here (e.g. WebUIScreenLocker has been destroyed),
706 // don't do anything, just return.
711 show_on_init_ = false;
716 gfx::NativeWindow SigninScreenHandler::GetNativeWindow() {
717 if (native_window_delegate_)
718 return native_window_delegate_->GetNativeWindow();
722 void SigninScreenHandler::RegisterMessages() {
723 AddCallback("authenticateUser", &SigninScreenHandler::HandleAuthenticateUser);
724 AddCallback("attemptUnlock", &SigninScreenHandler::HandleAttemptUnlock);
725 AddCallback("getUsers", &SigninScreenHandler::HandleGetUsers);
726 AddCallback("launchDemoUser", &SigninScreenHandler::HandleLaunchDemoUser);
727 AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito);
728 AddCallback("showSupervisedUserCreationScreen",
729 &SigninScreenHandler::HandleShowSupervisedUserCreationScreen);
730 AddCallback("launchPublicSession",
731 &SigninScreenHandler::HandleLaunchPublicSession);
732 AddRawCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin);
733 AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem);
734 AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser);
735 AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem);
736 AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper);
737 AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser);
738 AddCallback("toggleEnrollmentScreen",
739 &SigninScreenHandler::HandleToggleEnrollmentScreen);
740 AddCallback("toggleKioskEnableScreen",
741 &SigninScreenHandler::HandleToggleKioskEnableScreen);
742 AddCallback("createAccount", &SigninScreenHandler::HandleCreateAccount);
743 AddCallback("accountPickerReady",
744 &SigninScreenHandler::HandleAccountPickerReady);
745 AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady);
746 AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser);
747 AddCallback("openProxySettings",
748 &SigninScreenHandler::HandleOpenProxySettings);
749 AddCallback("loginVisible", &SigninScreenHandler::HandleLoginVisible);
750 AddCallback("cancelPasswordChangedFlow",
751 &SigninScreenHandler::HandleCancelPasswordChangedFlow);
752 AddCallback("cancelUserAdding",
753 &SigninScreenHandler::HandleCancelUserAdding);
754 AddCallback("migrateUserData", &SigninScreenHandler::HandleMigrateUserData);
755 AddCallback("resyncUserData", &SigninScreenHandler::HandleResyncUserData);
756 AddCallback("loginUIStateChanged",
757 &SigninScreenHandler::HandleLoginUIStateChanged);
758 AddCallback("unlockOnLoginSuccess",
759 &SigninScreenHandler::HandleUnlockOnLoginSuccess);
760 AddCallback("showLoadingTimeoutError",
761 &SigninScreenHandler::HandleShowLoadingTimeoutError);
762 AddCallback("updateOfflineLogin",
763 &SigninScreenHandler::HandleUpdateOfflineLogin);
764 AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
765 AddCallback("hardlockPod", &SigninScreenHandler::HandleHardlockPod);
766 AddCallback("retrieveAuthenticatedUserEmail",
767 &SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail);
768 AddCallback("getPublicSessionKeyboardLayouts",
769 &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
770 AddCallback("cancelConsumerManagementEnrollment",
771 &SigninScreenHandler::HandleCancelConsumerManagementEnrollment);
774 // This message is sent by the kiosk app menu, but is handled here
775 // so we can tell the delegate to launch the app.
776 AddCallback("launchKioskApp", &SigninScreenHandler::HandleLaunchKioskApp);
779 void SigninScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
780 registry->RegisterDictionaryPref(prefs::kUsersLRUInputMethod);
783 void SigninScreenHandler::HandleGetUsers() {
785 delegate_->HandleGetUsers();
788 void SigninScreenHandler::ClearAndEnablePassword() {
789 core_oobe_actor_->ResetSignInUI(false);
792 void SigninScreenHandler::ClearUserPodPassword() {
793 core_oobe_actor_->ClearUserPodPassword();
796 void SigninScreenHandler::RefocusCurrentPod() {
797 core_oobe_actor_->RefocusCurrentPod();
800 void SigninScreenHandler::OnUserRemoved(const std::string& username) {
801 CallJS("login.AccountPickerScreen.removeUser", username);
802 if (delegate_->GetUsers().empty())
806 void SigninScreenHandler::OnUserImageChanged(const user_manager::User& user) {
808 CallJS("login.AccountPickerScreen.updateUserImage", user.email());
811 void SigninScreenHandler::OnPreferencesChanged() {
812 // Make sure that one of the login UI is fully functional now, otherwise
813 // preferences update would be picked up next time it will be shown.
814 if (!webui_visible_) {
815 LOG(WARNING) << "Login UI is not active - postponed prefs change.";
816 preferences_changed_delayed_ = true;
820 if (delegate_ && !delegate_->IsShowUsers()) {
821 HandleShowAddUser(NULL);
824 delegate_->HandleGetUsers();
825 UpdateUIState(UI_STATE_ACCOUNT_PICKER, NULL);
827 preferences_changed_delayed_ = false;
830 void SigninScreenHandler::ResetSigninScreenHandlerDelegate() {
834 void SigninScreenHandler::ShowError(int login_attempts,
835 const std::string& error_text,
836 const std::string& help_link_text,
837 HelpAppLauncher::HelpTopic help_topic_id) {
838 core_oobe_actor_->ShowSignInError(login_attempts, error_text, help_link_text,
842 void SigninScreenHandler::ShowErrorScreen(LoginDisplay::SigninError error_id) {
844 case LoginDisplay::TPM_ERROR:
845 core_oobe_actor_->ShowTpmError();
848 NOTREACHED() << "Unknown sign in error";
853 void SigninScreenHandler::ShowSigninUI(const std::string& email) {
854 core_oobe_actor_->ShowSignInUI(email);
857 void SigninScreenHandler::ShowGaiaPasswordChanged(const std::string& username) {
858 gaia_screen_handler_->PasswordChangedFor(username);
859 gaia_screen_handler_->PopulateEmail(username);
860 core_oobe_actor_->ShowSignInUI(username);
861 CallJS("login.setAuthType",
863 static_cast<int>(ONLINE_SIGN_IN),
864 base::StringValue(""));
867 void SigninScreenHandler::ShowPasswordChangedDialog(bool show_password_error) {
868 core_oobe_actor_->ShowPasswordChangedScreen(show_password_error);
871 void SigninScreenHandler::ShowSigninScreenForCreds(
872 const std::string& username,
873 const std::string& password) {
874 DCHECK(gaia_screen_handler_);
875 gaia_screen_handler_->ShowSigninScreenForCreds(username, password);
878 void SigninScreenHandler::SetPublicSessionDisplayName(
879 const std::string& user_id,
880 const std::string& display_name) {
881 CallJS("login.AccountPickerScreen.setPublicSessionDisplayName",
886 void SigninScreenHandler::SetPublicSessionLocales(
887 const std::string& user_id,
888 scoped_ptr<base::ListValue> locales,
889 const std::string& default_locale,
890 bool multipleRecommendedLocales) {
891 CallJS("login.AccountPickerScreen.setPublicSessionLocales",
895 multipleRecommendedLocales);
898 void SigninScreenHandler::Observe(int type,
899 const content::NotificationSource& source,
900 const content::NotificationDetails& details) {
902 case chrome::NOTIFICATION_AUTH_NEEDED: {
903 has_pending_auth_ui_ = true;
906 case chrome::NOTIFICATION_AUTH_SUPPLIED:
907 has_pending_auth_ui_ = false;
908 // Reload auth extension as proxy credentials are supplied.
909 if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
911 update_state_closure_.Cancel();
913 case chrome::NOTIFICATION_AUTH_CANCELLED: {
914 // Don't reload auth extension if proxy auth dialog was cancelled.
915 has_pending_auth_ui_ = false;
916 update_state_closure_.Cancel();
920 NOTREACHED() << "Unexpected notification " << type;
924 void SigninScreenHandler::ShowBannerMessage(const base::string16& message) {
925 CallJS("login.AccountPickerScreen.showBannerMessage", message);
928 void SigninScreenHandler::ShowUserPodCustomIcon(
929 const std::string& username,
930 const ScreenlockBridge::UserPodCustomIconOptions& icon_options) {
931 scoped_ptr<base::DictionaryValue> icon = icon_options.ToDictionaryValue();
932 if (!icon || icon->empty())
934 CallJS("login.AccountPickerScreen.showUserPodCustomIcon", username, *icon);
937 void SigninScreenHandler::HideUserPodCustomIcon(const std::string& username) {
938 CallJS("login.AccountPickerScreen.hideUserPodCustomIcon", username);
941 void SigninScreenHandler::EnableInput() {
942 // Only for lock screen at the moment.
943 ScreenLocker::default_screen_locker()->EnableInput();
946 void SigninScreenHandler::SetAuthType(
947 const std::string& username,
948 ScreenlockBridge::LockHandler::AuthType auth_type,
949 const base::string16& initial_value) {
950 if (delegate_->GetAuthType(username) ==
951 ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD)
954 delegate_->SetAuthType(username, auth_type);
956 CallJS("login.AccountPickerScreen.setAuthType",
958 static_cast<int>(auth_type),
959 base::StringValue(initial_value));
962 ScreenlockBridge::LockHandler::AuthType SigninScreenHandler::GetAuthType(
963 const std::string& username) const {
964 return delegate_->GetAuthType(username);
967 void SigninScreenHandler::Unlock(const std::string& user_email) {
968 DCHECK(ScreenLocker::default_screen_locker());
969 ScreenLocker::Hide();
972 bool SigninScreenHandler::ShouldLoadGaia() const {
973 // Fetching of the extension is not started before account picker page is
974 // loaded because it can affect the loading speed.
975 // Do not load the extension for the screen locker, see crosbug.com/25018.
976 return !ScreenLocker::default_screen_locker() &&
977 is_account_picker_showing_first_time_;
980 // Update keyboard layout to least recently used by the user.
981 void SigninScreenHandler::SetUserInputMethod(const std::string& username) {
982 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
983 if (user_manager->IsUserLoggedIn()) {
984 // We are on sign-in screen inside user session (adding new user to
985 // the session or on lock screen), don't switch input methods in this case.
986 // TODO(dpolukhin): adding user and sign-in should be consistent
991 chromeos::input_method::InputMethodManager* const manager =
992 chromeos::input_method::InputMethodManager::Get();
994 const bool succeed = SetUserInputMethodImpl(username, manager);
996 // This is also a case when LRU layout is set only for a few local users,
997 // thus others need to be switched to default locale.
998 // Otherwise they will end up using another user's locale to log in.
1000 DVLOG(0) << "SetUserInputMethod('" << username
1001 << "'): failed to set user layout. Switching to default.";
1003 manager->SetInputMethodLoginDefault();
1008 void SigninScreenHandler::UserSettingsChanged() {
1009 DCHECK(gaia_screen_handler_);
1010 GaiaContext context;
1012 context.has_users = !delegate_->GetUsers().empty();
1013 gaia_screen_handler_->UpdateGaia(context);
1014 UpdateAddButtonStatus();
1017 void SigninScreenHandler::UpdateAddButtonStatus() {
1018 CallJS("cr.ui.login.DisplayManager.updateAddUserButtonStatus",
1019 AllWhitelistedUsersPresent());
1022 void SigninScreenHandler::HandleAuthenticateUser(const std::string& username,
1023 const std::string& password) {
1026 UserContext user_context(username);
1027 user_context.SetKey(Key(password));
1028 delegate_->Login(user_context, SigninSpecifics());
1031 void SigninScreenHandler::HandleAttemptUnlock(const std::string& username) {
1032 DCHECK(ScreenLocker::default_screen_locker());
1034 const user_manager::User* unlock_user = NULL;
1035 const user_manager::UserList& users = delegate_->GetUsers();
1036 for (user_manager::UserList::const_iterator it = users.begin();
1039 if ((*it)->email() == username) {
1047 Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(unlock_user);
1048 extensions::ScreenlockPrivateEventRouter* router =
1049 extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(
1051 router->OnAuthAttempted(GetAuthType(username), "");
1054 void SigninScreenHandler::HandleLaunchDemoUser() {
1055 UserContext context(user_manager::USER_TYPE_RETAIL_MODE, std::string());
1057 delegate_->Login(context, SigninSpecifics());
1060 void SigninScreenHandler::HandleLaunchIncognito() {
1061 UserContext context(user_manager::USER_TYPE_GUEST, std::string());
1063 delegate_->Login(context, SigninSpecifics());
1066 void SigninScreenHandler::HandleShowSupervisedUserCreationScreen() {
1067 if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
1068 LOG(ERROR) << "Managed users not allowed.";
1071 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
1072 LoginDisplayHostImpl::default_host()->
1073 StartWizard(WizardController::kSupervisedUserCreationScreenName,
1077 void SigninScreenHandler::HandleLaunchPublicSession(
1078 const std::string& user_id,
1079 const std::string& locale,
1080 const std::string& input_method) {
1084 UserContext context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user_id);
1085 context.SetPublicSessionLocale(locale),
1086 context.SetPublicSessionInputMethod(input_method);
1087 delegate_->Login(context, SigninSpecifics());
1090 void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) {
1091 if (!delegate_ || delegate_->IsShowUsers()) {
1096 args->GetString(0, &email);
1098 gaia_screen_handler_->PopulateEmail(email);
1099 // Load auth extension. Parameters are: force reload, do not load extension in
1100 // background, use offline version.
1101 gaia_screen_handler_->LoadAuthExtension(true, false, true);
1102 UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL);
1105 void SigninScreenHandler::HandleShutdownSystem() {
1106 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
1109 void SigninScreenHandler::HandleLoadWallpaper(const std::string& email) {
1111 delegate_->LoadWallpaper(email);
1114 void SigninScreenHandler::HandleRebootSystem() {
1115 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
1118 void SigninScreenHandler::HandleRemoveUser(const std::string& email) {
1121 delegate_->RemoveUser(email);
1122 UpdateAddButtonStatus();
1125 void SigninScreenHandler::HandleShowAddUser(const base::ListValue* args) {
1126 TRACE_EVENT_ASYNC_STEP_INTO0("ui",
1128 LoginDisplayHostImpl::kShowLoginWebUIid,
1131 // |args| can be null if it's OOBE.
1133 args->GetString(0, &email);
1134 gaia_screen_handler_->PopulateEmail(email);
1138 void SigninScreenHandler::HandleToggleEnrollmentScreen() {
1140 delegate_->ShowEnterpriseEnrollmentScreen();
1143 void SigninScreenHandler::HandleToggleKioskEnableScreen() {
1144 policy::BrowserPolicyConnectorChromeOS* connector =
1145 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1147 !auto_enrollment_progress_subscription_ &&
1148 !connector->IsEnterpriseManaged() &&
1149 LoginDisplayHostImpl::default_host()) {
1150 AutoEnrollmentController* auto_enrollment_controller =
1151 LoginDisplayHostImpl::default_host()->GetAutoEnrollmentController();
1152 auto_enrollment_progress_subscription_ =
1153 auto_enrollment_controller->RegisterProgressCallback(
1154 base::Bind(&SigninScreenHandler::ContinueKioskEnableFlow,
1155 weak_factory_.GetWeakPtr()));
1156 ContinueKioskEnableFlow(auto_enrollment_controller->state());
1160 void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() {
1161 policy::BrowserPolicyConnectorChromeOS* connector =
1162 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1163 if (delegate_ && !connector->IsEnterpriseManaged())
1164 delegate_->ShowKioskAutolaunchScreen();
1167 void SigninScreenHandler::LoadUsers(const base::ListValue& users_list,
1169 CallJS("login.AccountPickerScreen.loadUsers",
1171 delegate_->IsShowGuest());
1174 void SigninScreenHandler::HandleAccountPickerReady() {
1175 VLOG(0) << "Login WebUI >> AccountPickerReady";
1177 if (delegate_ && !ScreenLocker::default_screen_locker() &&
1178 !chromeos::IsMachineHWIDCorrect() &&
1180 delegate_->ShowWrongHWIDScreen();
1184 PrefService* prefs = g_browser_process->local_state();
1185 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
1186 if (core_oobe_actor_) {
1187 core_oobe_actor_->ShowDeviceResetScreen();
1192 is_account_picker_showing_first_time_ = true;
1193 gaia_screen_handler_->MaybePreloadAuthExtension();
1195 if (ScreenLocker::default_screen_locker()) {
1196 ScreenLocker::default_screen_locker()->delegate()->OnLockWebUIReady();
1197 ScreenlockBridge::Get()->SetLockHandler(this);
1201 delegate_->OnSigninScreenReady();
1204 void SigninScreenHandler::HandleWallpaperReady() {
1205 if (ScreenLocker::default_screen_locker()) {
1206 ScreenLocker::default_screen_locker()->delegate()->
1207 OnLockBackgroundDisplayed();
1211 void SigninScreenHandler::HandleSignOutUser() {
1213 delegate_->Signout();
1216 void SigninScreenHandler::HandleCreateAccount() {
1218 delegate_->CreateAccount();
1221 void SigninScreenHandler::HandleOpenProxySettings() {
1222 LoginDisplayHostImpl::default_host()->OpenProxySettings();
1225 void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
1226 VLOG(1) << "Login WebUI >> loginVisible, src: " << source << ", "
1227 << "webui_visible_: " << webui_visible_;
1228 if (!webui_visible_) {
1229 // There might be multiple messages from OOBE UI so send notifications after
1230 // the first one only.
1231 content::NotificationService::current()->Notify(
1232 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
1233 content::NotificationService::AllSources(),
1234 content::NotificationService::NoDetails());
1235 TRACE_EVENT_ASYNC_END0(
1236 "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid);
1238 webui_visible_ = true;
1239 if (preferences_changed_delayed_)
1240 OnPreferencesChanged();
1243 void SigninScreenHandler::HandleCancelPasswordChangedFlow() {
1244 gaia_screen_handler_->StartClearingCookies(
1245 base::Bind(&SigninScreenHandler::CancelPasswordChangedFlowInternal,
1246 weak_factory_.GetWeakPtr()));
1249 void SigninScreenHandler::HandleCancelUserAdding() {
1251 delegate_->CancelUserAdding();
1254 void SigninScreenHandler::HandleMigrateUserData(
1255 const std::string& old_password) {
1257 delegate_->MigrateUserData(old_password);
1260 void SigninScreenHandler::HandleResyncUserData() {
1262 delegate_->ResyncUserData();
1265 void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source,
1267 VLOG(0) << "Login WebUI >> active: " << new_value << ", "
1268 << "source: " << source;
1270 if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() &&
1271 KioskAppManager::Get()->IsAutoLaunchRequested()) {
1272 VLOG(0) << "Showing auto-launch warning";
1273 // On slow devices, the wallpaper animation is not shown initially, so we
1274 // must explicitly load the wallpaper. This is also the case for the
1275 // account-picker and gaia-signin UI states.
1276 delegate_->LoadSigninWallpaper();
1277 HandleToggleKioskAutolaunchScreen();
1281 if (source == kSourceGaiaSignin) {
1282 ui_state_ = UI_STATE_GAIA_SIGNIN;
1283 } else if (source == kSourceAccountPicker) {
1284 ui_state_ = UI_STATE_ACCOUNT_PICKER;
1291 void SigninScreenHandler::HandleUnlockOnLoginSuccess() {
1292 DCHECK(user_manager::UserManager::Get()->IsUserLoggedIn());
1293 if (ScreenLocker::default_screen_locker())
1294 ScreenLocker::default_screen_locker()->UnlockOnLoginSuccess();
1297 void SigninScreenHandler::HandleShowLoadingTimeoutError() {
1298 UpdateState(ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
1301 void SigninScreenHandler::HandleUpdateOfflineLogin(bool offline_login_active) {
1302 offline_login_active_ = offline_login_active;
1305 void SigninScreenHandler::HandleFocusPod(const std::string& user_id) {
1306 SetUserInputMethod(user_id);
1307 WallpaperManager::Get()->SetUserWallpaperDelayed(user_id);
1310 void SigninScreenHandler::HandleHardlockPod(const std::string& user_id) {
1311 SetAuthType(user_id,
1312 ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD,
1314 HideUserPodCustomIcon(user_id);
1317 void SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail(
1318 double attempt_token) {
1319 // TODO(antrim) : move GaiaSigninScreen dependency to GaiaSigninScreen.
1320 email_retriever_.reset(new AuthenticatedUserEmailRetriever(
1321 base::Bind(&SigninScreenHandler::CallJS<double, std::string>,
1322 base::Unretained(this),
1323 "login.GaiaSigninScreen.setAuthenticatedUserEmail",
1325 Profile::FromWebUI(web_ui())->GetRequestContext()));
1328 void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
1329 const std::string& user_id,
1330 const std::string& locale) {
1331 GetKeyboardLayoutsForLocale(
1332 base::Bind(&SigninScreenHandler::SendPublicSessionKeyboardLayouts,
1333 weak_factory_.GetWeakPtr(),
1339 void SigninScreenHandler::SendPublicSessionKeyboardLayouts(
1340 const std::string& user_id,
1341 const std::string& locale,
1342 scoped_ptr<base::ListValue> keyboard_layouts) {
1343 CallJS("login.AccountPickerScreen.setPublicSessionKeyboardLayouts",
1349 void SigninScreenHandler::HandleLaunchKioskApp(const std::string& app_id,
1350 bool diagnostic_mode) {
1351 UserContext context(user_manager::USER_TYPE_KIOSK_APP, app_id);
1352 SigninSpecifics specifics;
1353 specifics.kiosk_diagnostic_mode = diagnostic_mode;
1355 delegate_->Login(context, specifics);
1358 void SigninScreenHandler::HandleCancelConsumerManagementEnrollment() {
1359 policy::ConsumerManagementService* consumer_management =
1360 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
1361 GetConsumerManagementService();
1362 CHECK(consumer_management);
1363 consumer_management->SetEnrollmentState(
1364 policy::ConsumerManagementService::ENROLLMENT_CANCELED);
1365 is_enrolling_consumer_management_ = false;
1369 bool SigninScreenHandler::AllWhitelistedUsersPresent() {
1370 CrosSettings* cros_settings = CrosSettings::Get();
1371 bool allow_new_user = false;
1372 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
1375 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1376 const user_manager::UserList& users = user_manager->GetUsers();
1377 if (!delegate_ || users.size() > kMaxUsers) {
1380 const base::ListValue* whitelist = NULL;
1381 if (!cros_settings->GetList(kAccountsPrefUsers, &whitelist) || !whitelist)
1383 for (size_t i = 0; i < whitelist->GetSize(); ++i) {
1384 std::string whitelisted_user;
1385 // NB: Wildcards in the whitelist are also detected as not present here.
1386 if (!whitelist->GetString(i, &whitelisted_user) ||
1387 !user_manager->IsKnownUser(whitelisted_user)) {
1394 void SigninScreenHandler::CancelPasswordChangedFlowInternal() {
1397 delegate_->CancelPasswordChangedFlow();
1401 OobeUI::Screen SigninScreenHandler::GetCurrentScreen() const {
1402 OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
1403 OobeUI* oobe_ui = static_cast<OobeUI*>(web_ui()->GetController());
1405 screen = oobe_ui->current_screen();
1409 bool SigninScreenHandler::IsGaiaVisible() const {
1410 return IsSigninScreen(GetCurrentScreen()) &&
1411 ui_state_ == UI_STATE_GAIA_SIGNIN;
1414 bool SigninScreenHandler::IsGaiaHiddenByError() const {
1415 return IsSigninScreenHiddenByError() &&
1416 ui_state_ == UI_STATE_GAIA_SIGNIN;
1419 bool SigninScreenHandler::IsSigninScreenHiddenByError() const {
1420 return (GetCurrentScreen() == OobeUI::SCREEN_ERROR_MESSAGE) &&
1421 (IsSigninScreen(error_screen_actor_->parent_screen()));
1424 bool SigninScreenHandler::IsGuestSigninAllowed() const {
1425 CrosSettings* cros_settings = CrosSettings::Get();
1429 cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
1433 bool SigninScreenHandler::IsOfflineLoginAllowed() const {
1434 CrosSettings* cros_settings = CrosSettings::Get();
1438 // Offline login is allowed only when user pods are hidden.
1440 cros_settings->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_pods);
1444 void SigninScreenHandler::ContinueKioskEnableFlow(
1445 policy::AutoEnrollmentState state) {
1446 // Do not proceed with kiosk enable when auto enroll will be enforced.
1447 // TODO(xiyuan): Add an error UI feedkback so user knows what happens.
1449 case policy::AUTO_ENROLLMENT_STATE_IDLE:
1450 case policy::AUTO_ENROLLMENT_STATE_PENDING:
1451 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR:
1452 // Wait for the next callback.
1454 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT:
1455 // Auto-enrollment is on.
1456 LOG(WARNING) << "Kiosk enable flow aborted because auto enrollment is "
1457 "going to be enforced.";
1458 if (!kiosk_enable_flow_aborted_callback_for_test_.is_null())
1459 kiosk_enable_flow_aborted_callback_for_test_.Run();
1461 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR:
1462 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT:
1463 // Auto-enrollment not applicable.
1465 delegate_->ShowKioskEnableScreen();
1468 auto_enrollment_progress_subscription_.reset();
1471 void SigninScreenHandler::OnShowAddUser() {
1472 is_account_picker_showing_first_time_ = false;
1473 DCHECK(gaia_screen_handler_);
1474 gaia_screen_handler_->ShowGaia(is_enrolling_consumer_management_);
1477 GaiaScreenHandler::FrameState SigninScreenHandler::FrameState() const {
1478 DCHECK(gaia_screen_handler_);
1479 return gaia_screen_handler_->frame_state();
1482 net::Error SigninScreenHandler::FrameError() const {
1483 DCHECK(gaia_screen_handler_);
1484 return gaia_screen_handler_->frame_error();
1487 void SigninScreenHandler::OnCapsLockChanged(bool enabled) {
1488 caps_lock_enabled_ = enabled;
1489 if (page_is_ready())
1490 CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_);
1493 } // namespace chromeos