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 "ash/shell.h"
11 #include "ash/wm/lock_state_controller.h"
12 #include "base/bind.h"
13 #include "base/debug/trace_event.h"
14 #include "base/location.h"
15 #include "base/logging.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_registry_simple.h"
18 #include "base/prefs/pref_service.h"
19 #include "base/prefs/scoped_user_pref_update.h"
20 #include "base/strings/string16.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/sys_info.h"
25 #include "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/boot_times_loader.h"
31 #include "chrome/browser/chromeos/input_method/input_method_util.h"
32 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
33 #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
34 #include "chrome/browser/chromeos/login/hwid_checker.h"
35 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
36 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
37 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
38 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
39 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
40 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.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/device_local_account.h"
45 #include "chrome/browser/chromeos/profiles/profile_helper.h"
46 #include "chrome/browser/chromeos/settings/cros_settings.h"
47 #include "chrome/browser/io_thread.h"
48 #include "chrome/browser/profiles/profile.h"
49 #include "chrome/browser/signin/easy_unlock_service.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 "chrome/grit/chromium_strings.h"
58 #include "chrome/grit/generated_resources.h"
59 #include "chromeos/dbus/dbus_thread_manager.h"
60 #include "chromeos/dbus/power_manager_client.h"
61 #include "chromeos/ime/ime_keyboard.h"
62 #include "chromeos/ime/input_method_descriptor.h"
63 #include "chromeos/ime/input_method_manager.h"
64 #include "chromeos/login/auth/key.h"
65 #include "chromeos/login/auth/user_context.h"
66 #include "chromeos/network/network_state.h"
67 #include "chromeos/network/network_state_handler.h"
68 #include "chromeos/network/portal_detector/network_portal_detector.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/webui/web_ui_util.h"
78 #if !defined(USE_ATHENA)
79 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
84 // Max number of users to show.
85 const size_t kMaxUsers = 18;
87 // Timeout to delay first notification about offline state for a
89 const int kOfflineTimeoutSec = 5;
91 // Timeout used to prevent infinite connecting to a flaky network.
92 const int kConnectingTimeoutSec = 60;
94 // Type of the login screen UI that is currently presented to user.
95 const char kSourceGaiaSignin[] = "gaia-signin";
96 const char kSourceAccountPicker[] = "account-picker";
98 static bool Contains(const std::vector<std::string>& container,
99 const std::string& value) {
100 return std::find(container.begin(), container.end(), value) !=
106 explicit CallOnReturn(const base::Closure& callback)
107 : callback_(callback), call_scheduled_(false) {}
110 if (call_scheduled_ && !callback_.is_null())
114 void ScheduleCall() { call_scheduled_ = true; }
117 base::Closure callback_;
118 bool call_scheduled_;
120 DISALLOW_COPY_AND_ASSIGN(CallOnReturn);
129 bool IsOnline(NetworkStateInformer::State state,
130 ErrorScreenActor::ErrorReason reason) {
131 return state == NetworkStateInformer::ONLINE &&
132 reason != ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED &&
133 reason != ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT;
136 bool IsBehindCaptivePortal(NetworkStateInformer::State state,
137 ErrorScreenActor::ErrorReason reason) {
138 return state == NetworkStateInformer::CAPTIVE_PORTAL ||
139 reason == ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED;
142 bool IsProxyError(NetworkStateInformer::State state,
143 ErrorScreenActor::ErrorReason reason,
144 net::Error frame_error) {
145 return state == NetworkStateInformer::PROXY_AUTH_REQUIRED ||
146 reason == ErrorScreenActor::ERROR_REASON_PROXY_AUTH_CANCELLED ||
147 reason == ErrorScreenActor::ERROR_REASON_PROXY_CONNECTION_FAILED ||
148 (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
149 (frame_error == net::ERR_PROXY_CONNECTION_FAILED ||
150 frame_error == net::ERR_TUNNEL_CONNECTION_FAILED));
153 bool IsSigninScreen(const OobeUI::Screen screen) {
154 return screen == OobeUI::SCREEN_GAIA_SIGNIN ||
155 screen == OobeUI::SCREEN_ACCOUNT_PICKER;
158 bool IsSigninScreenError(ErrorScreen::ErrorState error_state) {
159 return error_state == ErrorScreen::ERROR_STATE_PORTAL ||
160 error_state == ErrorScreen::ERROR_STATE_OFFLINE ||
161 error_state == ErrorScreen::ERROR_STATE_PROXY ||
162 error_state == ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT;
165 // Returns network name by service path.
166 std::string GetNetworkName(const std::string& service_path) {
167 const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
168 GetNetworkState(service_path);
170 return std::string();
171 return network->name();
174 static bool SetUserInputMethodImpl(
175 const std::string& username,
176 const std::string& user_input_method,
177 input_method::InputMethodManager::State* ime_state) {
178 if (!chromeos::input_method::InputMethodManager::Get()->IsLoginKeyboard(
179 user_input_method)) {
180 LOG(WARNING) << "SetUserInputMethod('" << username
181 << "'): stored user LRU input method '" << user_input_method
182 << "' is no longer Full Latin Keyboard Language"
183 << " (entry dropped). Use hardware default instead.";
185 PrefService* const local_state = g_browser_process->local_state();
186 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
188 base::DictionaryValue* const users_lru_input_methods = updater.Get();
189 if (users_lru_input_methods != NULL) {
190 users_lru_input_methods->SetStringWithoutPathExpansion(username, "");
195 if (!Contains(ime_state->GetActiveInputMethodIds(), user_input_method)) {
196 if (!ime_state->EnableInputMethod(user_input_method)) {
197 DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username
198 << "'): user input method '" << user_input_method
199 << "' is not enabled and enabling failed (ignored!).";
202 ime_state->ChangeInputMethod(user_input_method, false /* show_message */);
209 // LoginScreenContext implementation ------------------------------------------
211 LoginScreenContext::LoginScreenContext() {
215 LoginScreenContext::LoginScreenContext(const base::ListValue* args) {
218 if (!args || args->GetSize() == 0)
221 if (args->GetString(0, &email))
225 void LoginScreenContext::Init() {
229 // SigninScreenHandler implementation ------------------------------------------
231 SigninScreenHandler::SigninScreenHandler(
232 const scoped_refptr<NetworkStateInformer>& network_state_informer,
233 ErrorScreenActor* error_screen_actor,
234 CoreOobeActor* core_oobe_actor,
235 GaiaScreenHandler* gaia_screen_handler)
236 : ui_state_(UI_STATE_UNKNOWN),
238 native_window_delegate_(NULL),
239 show_on_init_(false),
241 is_account_picker_showing_first_time_(false),
242 network_state_informer_(network_state_informer),
243 webui_visible_(false),
244 preferences_changed_delayed_(false),
245 error_screen_actor_(error_screen_actor),
246 core_oobe_actor_(core_oobe_actor),
247 is_first_update_state_call_(true),
248 offline_login_active_(false),
249 last_network_state_(NetworkStateInformer::UNKNOWN),
250 has_pending_auth_ui_(false),
251 caps_lock_enabled_(chromeos::input_method::InputMethodManager::Get()
253 ->CapsLockIsEnabled()),
254 gaia_screen_handler_(gaia_screen_handler),
255 oobe_ui_observer_added_(false),
256 histogram_helper_(new ErrorScreensHistogramHelper("Signin")),
257 weak_factory_(this) {
258 DCHECK(network_state_informer_.get());
259 DCHECK(error_screen_actor_);
260 DCHECK(core_oobe_actor_);
261 DCHECK(gaia_screen_handler_);
262 gaia_screen_handler_->SetSigninScreenHandler(this);
263 network_state_informer_->AddObserver(this);
266 chrome::NOTIFICATION_AUTH_NEEDED,
267 content::NotificationService::AllSources());
269 chrome::NOTIFICATION_AUTH_SUPPLIED,
270 content::NotificationService::AllSources());
272 chrome::NOTIFICATION_AUTH_CANCELLED,
273 content::NotificationService::AllSources());
275 chromeos::input_method::ImeKeyboard* keyboard =
276 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
278 keyboard->AddObserver(this);
280 #if !defined(USE_ATHENA)
281 max_mode_delegate_.reset(new TouchViewControllerDelegate());
282 max_mode_delegate_->AddObserver(this);
285 policy::ConsumerManagementService* consumer_management =
286 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
287 GetConsumerManagementService();
288 is_enrolling_consumer_management_ =
289 consumer_management &&
290 consumer_management->GetEnrollmentStage() ==
291 policy::ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED;
294 SigninScreenHandler::~SigninScreenHandler() {
295 OobeUI* oobe_ui = GetOobeUI();
296 if (oobe_ui && oobe_ui_observer_added_)
297 oobe_ui->RemoveObserver(this);
298 chromeos::input_method::ImeKeyboard* keyboard =
299 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
301 keyboard->RemoveObserver(this);
302 weak_factory_.InvalidateWeakPtrs();
304 delegate_->SetWebUIHandler(NULL);
305 network_state_informer_->RemoveObserver(this);
306 if (max_mode_delegate_) {
307 max_mode_delegate_->RemoveObserver(this);
308 max_mode_delegate_.reset(NULL);
310 ScreenlockBridge::Get()->SetLockHandler(NULL);
311 ScreenlockBridge::Get()->SetFocusedUser("");
314 void SigninScreenHandler::DeclareLocalizedValues(
315 LocalizedValuesBuilder* builder) {
316 builder->Add("passwordHint", IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT);
317 builder->Add("podMenuButtonAccessibleName",
318 IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME);
319 builder->Add("podMenuRemoveItemAccessibleName",
320 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME);
321 builder->Add("passwordFieldAccessibleName",
322 IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME);
323 builder->Add("signedIn", IDS_SCREEN_LOCK_ACTIVE_USER);
324 builder->Add("signinButton", IDS_LOGIN_BUTTON);
325 builder->Add("launchAppButton", IDS_LAUNCH_APP_BUTTON);
326 builder->Add("shutDown", IDS_SHUTDOWN_BUTTON);
327 builder->Add("addUser", IDS_ADD_USER_BUTTON);
328 builder->Add("browseAsGuest", IDS_GO_INCOGNITO_BUTTON);
329 builder->Add("cancel", IDS_CANCEL);
330 builder->Add("signOutUser", IDS_SCREEN_LOCK_SIGN_OUT);
331 builder->Add("offlineLogin", IDS_OFFLINE_LOGIN_HTML);
332 builder->Add("ownerUserPattern", IDS_LOGIN_POD_OWNER_USER);
333 builder->Add("removeUser", IDS_LOGIN_POD_REMOVE_USER);
334 builder->Add("errorTpmFailureTitle", IDS_LOGIN_ERROR_TPM_FAILURE_TITLE);
335 builder->Add("errorTpmFailureReboot", IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT);
336 builder->Add("errorTpmFailureRebootButton",
337 IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT_BUTTON);
339 policy::BrowserPolicyConnectorChromeOS* connector =
340 g_browser_process->platform_part()->browser_policy_connector_chromeos();
341 builder->Add("disabledAddUserTooltip",
342 connector->IsEnterpriseManaged()
343 ? IDS_DISABLED_ADD_USER_TOOLTIP_ENTERPRISE
344 : IDS_DISABLED_ADD_USER_TOOLTIP);
346 builder->Add("supervisedUserExpiredTokenWarning",
347 IDS_SUPERVISED_USER_EXPIRED_TOKEN_WARNING);
348 builder->Add("signinBannerText", IDS_LOGIN_USER_ADDING_BANNER);
350 // Multi-profiles related strings.
351 builder->Add("multiProfilesRestrictedPolicyTitle",
352 IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE);
353 builder->Add("multiProfilesNotAllowedPolicyMsg",
354 IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG);
355 builder->Add("multiProfilesPrimaryOnlyPolicyMsg",
356 IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG);
357 builder->Add("multiProfilesOwnerPrimaryOnlyMsg",
358 IDS_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG);
360 // Strings used by password changed dialog.
361 builder->Add("passwordChangedTitle", IDS_LOGIN_PASSWORD_CHANGED_TITLE);
362 builder->Add("passwordChangedDesc", IDS_LOGIN_PASSWORD_CHANGED_DESC);
363 builder->AddF("passwordChangedMoreInfo",
364 IDS_LOGIN_PASSWORD_CHANGED_MORE_INFO,
365 IDS_SHORT_PRODUCT_OS_NAME);
367 builder->Add("oldPasswordHint", IDS_LOGIN_PASSWORD_CHANGED_OLD_PASSWORD_HINT);
368 builder->Add("oldPasswordIncorrect",
369 IDS_LOGIN_PASSWORD_CHANGED_INCORRECT_OLD_PASSWORD);
370 builder->Add("passwordChangedCantRemember",
371 IDS_LOGIN_PASSWORD_CHANGED_CANT_REMEMBER);
372 builder->Add("passwordChangedBackButton",
373 IDS_LOGIN_PASSWORD_CHANGED_BACK_BUTTON);
374 builder->Add("passwordChangedsOkButton", IDS_OK);
375 builder->Add("passwordChangedProceedAnyway",
376 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY);
377 builder->Add("proceedAnywayButton",
378 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY_BUTTON);
379 builder->Add("publicAccountInfoFormat", IDS_LOGIN_PUBLIC_ACCOUNT_INFO_FORMAT);
380 builder->Add("publicAccountReminder",
381 IDS_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER);
382 builder->Add("publicSessionLanguageAndInput",
383 IDS_LOGIN_PUBLIC_SESSION_LANGUAGE_AND_INPUT);
384 builder->Add("publicAccountEnter", IDS_LOGIN_PUBLIC_ACCOUNT_ENTER);
385 builder->Add("publicAccountEnterAccessibleName",
386 IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME);
387 builder->Add("publicSessionSelectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
388 builder->Add("publicSessionSelectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
389 builder->Add("removeUserWarningText",
391 builder->AddF("removeSupervisedUserWarningText",
392 IDS_LOGIN_POD_SUPERVISED_USER_REMOVE_WARNING,
393 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL));
394 builder->Add("removeUserWarningButtonTitle",
395 IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON);
397 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE);
399 builder->Add("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE);
400 builder->Add("confirmPasswordLabel", IDS_LOGIN_CONFIRM_PASSWORD_LABEL);
401 builder->Add("confirmPasswordConfirmButton",
402 IDS_LOGIN_CONFIRM_PASSWORD_CONFIRM_BUTTON);
403 builder->Add("confirmPasswordText", IDS_LOGIN_CONFIRM_PASSWORD_TEXT);
404 builder->Add("confirmPasswordErrorText",
405 IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT);
407 builder->Add("fatalEnrollmentError",
408 IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR);
409 builder->Add("insecureURLEnrollmentError",
410 IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR);
412 if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled())
413 builder->Add("demoLoginMessage", IDS_KIOSK_MODE_LOGIN_MESSAGE);
416 void SigninScreenHandler::Show(const LoginScreenContext& context) {
419 // Just initialize internal fields from context and call ShowImpl().
420 oobe_ui_ = context.oobe_ui();
423 if (is_enrolling_consumer_management_) {
424 // We don't check if the value of the owner e-mail is trusted because it is
425 // only used to pre-fill the e-mail field in Gaia sign-in page and a cached
426 // value is sufficient.
427 CrosSettings::Get()->GetString(kDeviceOwner, &email);
429 email = context.email();
431 gaia_screen_handler_->PopulateEmail(email);
433 histogram_helper_->OnScreenShow();
436 void SigninScreenHandler::ShowRetailModeLoginSpinner() {
437 CallJS("showLoginSpinner");
440 void SigninScreenHandler::SetDelegate(SigninScreenHandlerDelegate* delegate) {
441 delegate_ = delegate;
443 delegate_->SetWebUIHandler(this);
445 auto_enrollment_progress_subscription_.reset();
448 void SigninScreenHandler::SetNativeWindowDelegate(
449 NativeWindowDelegate* native_window_delegate) {
450 native_window_delegate_ = native_window_delegate;
453 void SigninScreenHandler::OnNetworkReady() {
454 VLOG(1) << "OnNetworkReady() call.";
455 DCHECK(gaia_screen_handler_);
456 gaia_screen_handler_->MaybePreloadAuthExtension();
459 void SigninScreenHandler::UpdateState(ErrorScreenActor::ErrorReason reason) {
460 UpdateStateInternal(reason, false);
463 void SigninScreenHandler::SetFocusPODCallbackForTesting(
464 base::Closure callback) {
465 test_focus_pod_callback_ = callback;
468 // SigninScreenHandler, private: -----------------------------------------------
470 void SigninScreenHandler::ShowImpl() {
471 if (!page_is_ready()) {
472 show_on_init_ = true;
476 if (!ime_state_.get())
477 ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState();
479 if (!oobe_ui_observer_added_) {
480 oobe_ui_observer_added_ = true;
481 GetOobeUI()->AddObserver(this);
484 if (oobe_ui_ || is_enrolling_consumer_management_) {
485 // Shows new user sign-in for OOBE.
488 // Populates account picker. Animation is turned off for now until we
489 // figure out how to make it fast enough.
490 delegate_->HandleGetUsers();
492 // Reset Caps Lock state when login screen is shown.
493 input_method::InputMethodManager::Get()
495 ->SetCapsLockEnabled(false);
497 base::DictionaryValue params;
498 params.SetBoolean("disableAddUser", AllWhitelistedUsersPresent());
499 UpdateUIState(UI_STATE_ACCOUNT_PICKER, ¶ms);
503 void SigninScreenHandler::UpdateUIState(UIState ui_state,
504 base::DictionaryValue* params) {
506 case UI_STATE_GAIA_SIGNIN:
507 ui_state_ = UI_STATE_GAIA_SIGNIN;
508 ShowScreen(OobeUI::kScreenGaiaSignin, params);
510 case UI_STATE_ACCOUNT_PICKER:
511 ui_state_ = UI_STATE_ACCOUNT_PICKER;
512 ShowScreen(OobeUI::kScreenAccountPicker, params);
520 // TODO(ygorshenin@): split this method into small parts.
521 // TODO(ygorshenin@): move this logic to GaiaScreenHandler.
522 void SigninScreenHandler::UpdateStateInternal(
523 ErrorScreenActor::ErrorReason reason,
525 // Do nothing once user has signed in or sign in is in progress.
526 // TODO(ygorshenin): We will end up here when processing network state
527 // notification but no ShowSigninScreen() was called so delegate_ will be
528 // NULL. Network state processing logic does not belong here.
530 (delegate_->IsUserSigninCompleted() || delegate_->IsSigninInProgress())) {
534 NetworkStateInformer::State state = network_state_informer_->state();
535 const std::string network_path = network_state_informer_->network_path();
536 const std::string network_name = GetNetworkName(network_path);
538 // Skip "update" notification about OFFLINE state from
539 // NetworkStateInformer if previous notification already was
541 if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) &&
542 !force_update && !update_state_closure_.IsCancelled()) {
546 update_state_closure_.Cancel();
548 if ((state == NetworkStateInformer::OFFLINE && !force_update) ||
549 has_pending_auth_ui_) {
550 update_state_closure_.Reset(
551 base::Bind(&SigninScreenHandler::UpdateStateInternal,
552 weak_factory_.GetWeakPtr(),
555 base::MessageLoop::current()->PostDelayedTask(
557 update_state_closure_.callback(),
558 base::TimeDelta::FromSeconds(kOfflineTimeoutSec));
562 // Don't show or hide error screen if we're in connecting state.
563 if (state == NetworkStateInformer::CONNECTING && !force_update) {
564 if (connecting_closure_.IsCancelled()) {
565 // First notification about CONNECTING state.
566 connecting_closure_.Reset(
567 base::Bind(&SigninScreenHandler::UpdateStateInternal,
568 weak_factory_.GetWeakPtr(),
571 base::MessageLoop::current()->PostDelayedTask(
573 connecting_closure_.callback(),
574 base::TimeDelta::FromSeconds(kConnectingTimeoutSec));
578 connecting_closure_.Cancel();
580 const bool is_online = IsOnline(state, reason);
581 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
582 const bool is_gaia_loading_timeout =
583 (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
584 const bool is_gaia_error =
585 FrameError() != net::OK && FrameError() != net::ERR_NETWORK_CHANGED;
586 const bool is_gaia_signin = IsGaiaVisible() || IsGaiaHiddenByError();
587 const bool error_screen_should_overlay =
588 !offline_login_active_ && IsGaiaVisible();
589 const bool from_not_online_to_online_transition =
590 is_online && last_network_state_ != NetworkStateInformer::ONLINE;
591 last_network_state_ = state;
593 CallOnReturn reload_gaia(base::Bind(
594 &SigninScreenHandler::ReloadGaia, weak_factory_.GetWeakPtr(), true));
596 if (is_online || !is_behind_captive_portal)
597 error_screen_actor_->HideCaptivePortal();
599 // Hide offline message (if needed) and return if current screen is
601 if (!is_gaia_signin) {
602 if (!IsSigninScreenHiddenByError())
603 HideOfflineMessage(state, reason);
607 // Reload frame if network state is changed from {!ONLINE} -> ONLINE state.
608 if (reason == ErrorScreenActor::ERROR_REASON_NETWORK_STATE_CHANGED &&
609 from_not_online_to_online_transition) {
610 // Schedules a immediate retry.
611 LOG(WARNING) << "Retry frame load since network has been changed.";
612 reload_gaia.ScheduleCall();
615 if (reason == ErrorScreenActor::ERROR_REASON_PROXY_CONFIG_CHANGED &&
616 error_screen_should_overlay) {
617 // Schedules a immediate retry.
618 LOG(WARNING) << "Retry frameload since proxy settings has been changed.";
619 reload_gaia.ScheduleCall();
622 if (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
623 !IsProxyError(state, reason, FrameError())) {
624 LOG(WARNING) << "Retry frame load due to reason: "
625 << ErrorScreenActor::ErrorReasonString(reason);
626 reload_gaia.ScheduleCall();
629 if (is_gaia_loading_timeout) {
630 LOG(WARNING) << "Retry frame load due to loading timeout.";
631 reload_gaia.ScheduleCall();
634 if ((!is_online || is_gaia_loading_timeout || is_gaia_error) &&
635 !offline_login_active_) {
636 SetupAndShowOfflineMessage(state, reason);
638 HideOfflineMessage(state, reason);
642 void SigninScreenHandler::SetupAndShowOfflineMessage(
643 NetworkStateInformer:: State state,
644 ErrorScreenActor::ErrorReason reason) {
645 const std::string network_path = network_state_informer_->network_path();
646 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
647 const bool is_proxy_error = IsProxyError(state, reason, FrameError());
648 const bool is_gaia_loading_timeout =
649 (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
651 if (is_proxy_error) {
652 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PROXY,
654 } else if (is_behind_captive_portal) {
655 // Do not bother a user with obsessive captive portal showing. This
656 // check makes captive portal being shown only once: either when error
657 // screen is shown for the first time or when switching from another
658 // error screen (offline, proxy).
659 if (IsGaiaVisible() ||
660 (error_screen_actor_->error_state() !=
661 ErrorScreen::ERROR_STATE_PORTAL)) {
662 error_screen_actor_->FixCaptivePortal();
664 const std::string network_name = GetNetworkName(network_path);
665 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PORTAL,
667 } else if (is_gaia_loading_timeout) {
668 error_screen_actor_->SetErrorState(
669 ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT, std::string());
671 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE,
675 const bool guest_signin_allowed = IsGuestSigninAllowed() &&
676 IsSigninScreenError(error_screen_actor_->error_state());
677 error_screen_actor_->AllowGuestSignin(guest_signin_allowed);
679 const bool offline_login_allowed = IsOfflineLoginAllowed() &&
680 IsSigninScreenError(error_screen_actor_->error_state()) &&
681 error_screen_actor_->error_state() !=
682 ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT;
683 error_screen_actor_->AllowOfflineLogin(offline_login_allowed);
685 if (GetCurrentScreen() != OobeUI::SCREEN_ERROR_MESSAGE) {
686 base::DictionaryValue params;
687 const std::string network_type = network_state_informer_->network_type();
688 params.SetString("lastNetworkType", network_type);
689 error_screen_actor_->SetUIState(ErrorScreen::UI_STATE_SIGNIN);
690 error_screen_actor_->Show(OobeUI::SCREEN_GAIA_SIGNIN, ¶ms);
691 histogram_helper_->OnErrorShow(error_screen_actor_->error_state());
695 void SigninScreenHandler::HideOfflineMessage(
696 NetworkStateInformer::State state,
697 ErrorScreenActor::ErrorReason reason) {
698 if (!IsSigninScreenHiddenByError())
701 error_screen_actor_->Hide();
702 histogram_helper_->OnErrorHide();
704 // Forces a reload for Gaia screen on hiding error message.
705 if (IsGaiaVisible() || IsGaiaHiddenByError())
709 void SigninScreenHandler::ReloadGaia(bool force_reload) {
710 gaia_screen_handler_->ReloadGaia(force_reload);
713 void SigninScreenHandler::Initialize() {
714 // If delegate_ is NULL here (e.g. WebUIScreenLocker has been destroyed),
715 // don't do anything, just return.
720 show_on_init_ = false;
725 gfx::NativeWindow SigninScreenHandler::GetNativeWindow() {
726 if (native_window_delegate_)
727 return native_window_delegate_->GetNativeWindow();
731 void SigninScreenHandler::RegisterMessages() {
732 AddCallback("authenticateUser", &SigninScreenHandler::HandleAuthenticateUser);
733 AddCallback("attemptUnlock", &SigninScreenHandler::HandleAttemptUnlock);
734 AddCallback("getUsers", &SigninScreenHandler::HandleGetUsers);
735 AddCallback("launchDemoUser", &SigninScreenHandler::HandleLaunchDemoUser);
736 AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito);
737 AddCallback("showSupervisedUserCreationScreen",
738 &SigninScreenHandler::HandleShowSupervisedUserCreationScreen);
739 AddCallback("launchPublicSession",
740 &SigninScreenHandler::HandleLaunchPublicSession);
741 AddRawCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin);
742 AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem);
743 AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser);
744 AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem);
745 AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper);
746 AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser);
747 AddCallback("toggleEnrollmentScreen",
748 &SigninScreenHandler::HandleToggleEnrollmentScreen);
749 AddCallback("switchToEmbeddedSignin",
750 &SigninScreenHandler::HandleSwitchToEmbeddedSignin);
751 AddCallback("toggleKioskEnableScreen",
752 &SigninScreenHandler::HandleToggleKioskEnableScreen);
753 AddCallback("createAccount", &SigninScreenHandler::HandleCreateAccount);
754 AddCallback("accountPickerReady",
755 &SigninScreenHandler::HandleAccountPickerReady);
756 AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady);
757 AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser);
758 AddCallback("openProxySettings",
759 &SigninScreenHandler::HandleOpenProxySettings);
760 AddCallback("loginVisible", &SigninScreenHandler::HandleLoginVisible);
761 AddCallback("cancelPasswordChangedFlow",
762 &SigninScreenHandler::HandleCancelPasswordChangedFlow);
763 AddCallback("cancelUserAdding",
764 &SigninScreenHandler::HandleCancelUserAdding);
765 AddCallback("migrateUserData", &SigninScreenHandler::HandleMigrateUserData);
766 AddCallback("resyncUserData", &SigninScreenHandler::HandleResyncUserData);
767 AddCallback("loginUIStateChanged",
768 &SigninScreenHandler::HandleLoginUIStateChanged);
769 AddCallback("unlockOnLoginSuccess",
770 &SigninScreenHandler::HandleUnlockOnLoginSuccess);
771 AddCallback("showLoadingTimeoutError",
772 &SigninScreenHandler::HandleShowLoadingTimeoutError);
773 AddCallback("updateOfflineLogin",
774 &SigninScreenHandler::HandleUpdateOfflineLogin);
775 AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
776 AddCallback("hardlockPod", &SigninScreenHandler::HandleHardlockPod);
777 AddCallback("getPublicSessionKeyboardLayouts",
778 &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
779 AddCallback("cancelConsumerManagementEnrollment",
780 &SigninScreenHandler::HandleCancelConsumerManagementEnrollment);
781 AddCallback("getTouchViewState",
782 &SigninScreenHandler::HandleGetTouchViewState);
785 // This message is sent by the kiosk app menu, but is handled here
786 // so we can tell the delegate to launch the app.
787 AddCallback("launchKioskApp", &SigninScreenHandler::HandleLaunchKioskApp);
790 void SigninScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
791 registry->RegisterDictionaryPref(prefs::kUsersLRUInputMethod);
794 void SigninScreenHandler::OnCurrentScreenChanged(OobeUI::Screen current_screen,
795 OobeUI::Screen new_screen) {
796 if (new_screen == OobeUI::SCREEN_ACCOUNT_PICKER) {
797 // Restore active IME state if returning to user pod row screen.
798 input_method::InputMethodManager::Get()->SetState(ime_state_);
802 std::string SigninScreenHandler::GetUserLRUInputMethod(
803 const std::string& username) const {
804 PrefService* const local_state = g_browser_process->local_state();
805 const base::DictionaryValue* users_lru_input_methods =
806 local_state->GetDictionary(prefs::kUsersLRUInputMethod);
808 if (users_lru_input_methods == NULL) {
809 DLOG(WARNING) << "GetUserLRUInputMethod('" << username
810 << "'): no kUsersLRUInputMethod";
811 return std::string();
814 std::string input_method;
816 if (!users_lru_input_methods->GetStringWithoutPathExpansion(username,
818 DVLOG(0) << "GetUserLRUInputMethod('" << username
819 << "'): no input method for this user";
820 return std::string();
826 void SigninScreenHandler::HandleGetUsers() {
828 delegate_->HandleGetUsers();
831 void SigninScreenHandler::ClearAndEnablePassword() {
832 core_oobe_actor_->ResetSignInUI(false);
835 void SigninScreenHandler::ClearUserPodPassword() {
836 core_oobe_actor_->ClearUserPodPassword();
839 void SigninScreenHandler::RefocusCurrentPod() {
840 core_oobe_actor_->RefocusCurrentPod();
843 void SigninScreenHandler::OnUserRemoved(const std::string& username) {
844 CallJS("login.AccountPickerScreen.removeUser", username);
845 if (delegate_->GetUsers().empty())
849 void SigninScreenHandler::OnUserImageChanged(const user_manager::User& user) {
851 CallJS("login.AccountPickerScreen.updateUserImage", user.email());
854 void SigninScreenHandler::OnPreferencesChanged() {
855 // Make sure that one of the login UI is fully functional now, otherwise
856 // preferences update would be picked up next time it will be shown.
857 if (!webui_visible_) {
858 LOG(WARNING) << "Login UI is not active - postponed prefs change.";
859 preferences_changed_delayed_ = true;
863 if (delegate_ && !delegate_->IsShowUsers()) {
864 HandleShowAddUser(NULL);
867 delegate_->HandleGetUsers();
868 UpdateUIState(UI_STATE_ACCOUNT_PICKER, NULL);
870 preferences_changed_delayed_ = false;
873 void SigninScreenHandler::ResetSigninScreenHandlerDelegate() {
877 void SigninScreenHandler::ShowError(int login_attempts,
878 const std::string& error_text,
879 const std::string& help_link_text,
880 HelpAppLauncher::HelpTopic help_topic_id) {
881 core_oobe_actor_->ShowSignInError(login_attempts, error_text, help_link_text,
885 void SigninScreenHandler::ShowErrorScreen(LoginDisplay::SigninError error_id) {
887 case LoginDisplay::TPM_ERROR:
888 core_oobe_actor_->ShowTpmError();
891 NOTREACHED() << "Unknown sign in error";
896 void SigninScreenHandler::ShowSigninUI(const std::string& email) {
897 core_oobe_actor_->ShowSignInUI(email);
900 void SigninScreenHandler::ShowGaiaPasswordChanged(const std::string& username) {
901 gaia_screen_handler_->PasswordChangedFor(username);
902 gaia_screen_handler_->PopulateEmail(username);
903 core_oobe_actor_->ShowSignInUI(username);
904 CallJS("login.setAuthType",
906 static_cast<int>(ONLINE_SIGN_IN),
907 base::StringValue(""));
910 void SigninScreenHandler::ShowPasswordChangedDialog(bool show_password_error) {
911 core_oobe_actor_->ShowPasswordChangedScreen(show_password_error);
914 void SigninScreenHandler::ShowSigninScreenForCreds(
915 const std::string& username,
916 const std::string& password) {
917 DCHECK(gaia_screen_handler_);
918 gaia_screen_handler_->ShowSigninScreenForCreds(username, password);
921 void SigninScreenHandler::SetPublicSessionDisplayName(
922 const std::string& user_id,
923 const std::string& display_name) {
924 CallJS("login.AccountPickerScreen.setPublicSessionDisplayName",
929 void SigninScreenHandler::SetPublicSessionLocales(
930 const std::string& user_id,
931 scoped_ptr<base::ListValue> locales,
932 const std::string& default_locale,
933 bool multipleRecommendedLocales) {
934 CallJS("login.AccountPickerScreen.setPublicSessionLocales",
938 multipleRecommendedLocales);
941 void SigninScreenHandler::Observe(int type,
942 const content::NotificationSource& source,
943 const content::NotificationDetails& details) {
945 case chrome::NOTIFICATION_AUTH_NEEDED: {
946 has_pending_auth_ui_ = true;
949 case chrome::NOTIFICATION_AUTH_SUPPLIED:
950 has_pending_auth_ui_ = false;
951 // Reload auth extension as proxy credentials are supplied.
952 if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
954 update_state_closure_.Cancel();
956 case chrome::NOTIFICATION_AUTH_CANCELLED: {
957 // Don't reload auth extension if proxy auth dialog was cancelled.
958 has_pending_auth_ui_ = false;
959 update_state_closure_.Cancel();
963 NOTREACHED() << "Unexpected notification " << type;
967 void SigninScreenHandler::ShowBannerMessage(const base::string16& message) {
968 CallJS("login.AccountPickerScreen.showBannerMessage", message);
971 void SigninScreenHandler::ShowUserPodCustomIcon(
972 const std::string& username,
973 const ScreenlockBridge::UserPodCustomIconOptions& icon_options) {
974 scoped_ptr<base::DictionaryValue> icon = icon_options.ToDictionaryValue();
975 if (!icon || icon->empty())
977 CallJS("login.AccountPickerScreen.showUserPodCustomIcon", username, *icon);
980 void SigninScreenHandler::HideUserPodCustomIcon(const std::string& username) {
981 CallJS("login.AccountPickerScreen.hideUserPodCustomIcon", username);
984 void SigninScreenHandler::EnableInput() {
985 // Only for lock screen at the moment.
986 ScreenLocker::default_screen_locker()->EnableInput();
989 void SigninScreenHandler::SetAuthType(
990 const std::string& username,
991 ScreenlockBridge::LockHandler::AuthType auth_type,
992 const base::string16& initial_value) {
993 if (delegate_->GetAuthType(username) ==
994 ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD)
997 delegate_->SetAuthType(username, auth_type);
999 CallJS("login.AccountPickerScreen.setAuthType",
1001 static_cast<int>(auth_type),
1002 base::StringValue(initial_value));
1005 ScreenlockBridge::LockHandler::AuthType SigninScreenHandler::GetAuthType(
1006 const std::string& username) const {
1007 return delegate_->GetAuthType(username);
1010 void SigninScreenHandler::Unlock(const std::string& user_email) {
1011 DCHECK(ScreenLocker::default_screen_locker());
1012 ScreenLocker::Hide();
1015 void SigninScreenHandler::AttemptEasySignin(const std::string& user_email,
1016 const std::string& secret,
1017 const std::string& key_label) {
1018 DCHECK(!ScreenLocker::default_screen_locker());
1022 UserContext user_context(user_email);
1023 user_context.SetAuthFlow(UserContext::AUTH_FLOW_EASY_UNLOCK);
1024 user_context.SetKey(Key(secret));
1025 user_context.GetKey()->SetLabel(key_label);
1027 delegate_->Login(user_context, SigninSpecifics());
1030 void SigninScreenHandler::OnMaximizeModeStarted() {
1031 CallJS("login.AccountPickerScreen.setTouchViewState", true);
1034 void SigninScreenHandler::OnMaximizeModeEnded() {
1035 CallJS("login.AccountPickerScreen.setTouchViewState", false);
1038 bool SigninScreenHandler::ShouldLoadGaia() const {
1039 // Fetching of the extension is not started before account picker page is
1040 // loaded because it can affect the loading speed.
1041 // Do not load the extension for the screen locker, see crosbug.com/25018.
1042 return !ScreenLocker::default_screen_locker() &&
1043 is_account_picker_showing_first_time_;
1046 // Update keyboard layout to least recently used by the user.
1047 void SigninScreenHandler::SetUserInputMethod(
1048 const std::string& username,
1049 input_method::InputMethodManager::State* ime_state) {
1050 bool succeed = false;
1052 const std::string input_method = GetUserLRUInputMethod(username);
1054 if (!input_method.empty())
1055 succeed = SetUserInputMethodImpl(username, input_method, ime_state);
1057 // This is also a case when LRU layout is set only for a few local users,
1058 // thus others need to be switched to default locale.
1059 // Otherwise they will end up using another user's locale to log in.
1061 DVLOG(0) << "SetUserInputMethod('" << username
1062 << "'): failed to set user layout. Switching to default.";
1064 ime_state->SetInputMethodLoginDefault();
1069 void SigninScreenHandler::UserSettingsChanged() {
1070 DCHECK(gaia_screen_handler_);
1071 GaiaContext context;
1073 context.has_users = !delegate_->GetUsers().empty();
1074 gaia_screen_handler_->UpdateGaia(context);
1075 UpdateAddButtonStatus();
1078 void SigninScreenHandler::UpdateAddButtonStatus() {
1079 CallJS("cr.ui.login.DisplayManager.updateAddUserButtonStatus",
1080 AllWhitelistedUsersPresent());
1083 void SigninScreenHandler::HandleAuthenticateUser(const std::string& username,
1084 const std::string& password) {
1087 UserContext user_context(username);
1088 user_context.SetKey(Key(password));
1089 delegate_->Login(user_context, SigninSpecifics());
1092 void SigninScreenHandler::HandleAttemptUnlock(const std::string& username) {
1093 EasyUnlockService* service = GetEasyUnlockServiceForUser(username);
1096 service->AttemptAuth(username);
1099 void SigninScreenHandler::HandleLaunchDemoUser() {
1100 UserContext context(user_manager::USER_TYPE_RETAIL_MODE, std::string());
1102 delegate_->Login(context, SigninSpecifics());
1105 void SigninScreenHandler::HandleLaunchIncognito() {
1106 UserContext context(user_manager::USER_TYPE_GUEST, std::string());
1108 delegate_->Login(context, SigninSpecifics());
1111 void SigninScreenHandler::HandleShowSupervisedUserCreationScreen() {
1112 if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
1113 LOG(ERROR) << "Managed users not allowed.";
1116 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
1117 LoginDisplayHostImpl::default_host()->
1118 StartWizard(WizardController::kSupervisedUserCreationScreenName,
1122 void SigninScreenHandler::HandleLaunchPublicSession(
1123 const std::string& user_id,
1124 const std::string& locale,
1125 const std::string& input_method) {
1129 UserContext context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user_id);
1130 context.SetPublicSessionLocale(locale),
1131 context.SetPublicSessionInputMethod(input_method);
1132 delegate_->Login(context, SigninSpecifics());
1135 void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) {
1136 if (!delegate_ || delegate_->IsShowUsers()) {
1141 args->GetString(0, &email);
1143 gaia_screen_handler_->PopulateEmail(email);
1144 // Load auth extension. Parameters are: force reload, do not load extension in
1145 // background, use offline version.
1146 gaia_screen_handler_->LoadAuthExtension(true, false, true);
1147 UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL);
1150 void SigninScreenHandler::HandleShutdownSystem() {
1151 #if defined(USE_ATHENA)
1152 chromeos::DBusThreadManager::Get()->
1153 GetPowerManagerClient()->RequestShutdown();
1155 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
1159 void SigninScreenHandler::HandleLoadWallpaper(const std::string& email) {
1161 delegate_->LoadWallpaper(email);
1164 void SigninScreenHandler::HandleRebootSystem() {
1165 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
1168 void SigninScreenHandler::HandleRemoveUser(const std::string& email) {
1171 delegate_->RemoveUser(email);
1172 UpdateAddButtonStatus();
1175 void SigninScreenHandler::HandleShowAddUser(const base::ListValue* args) {
1176 TRACE_EVENT_ASYNC_STEP_INTO0("ui",
1178 LoginDisplayHostImpl::kShowLoginWebUIid,
1181 // |args| can be null if it's OOBE.
1183 args->GetString(0, &email);
1184 gaia_screen_handler_->PopulateEmail(email);
1188 void SigninScreenHandler::HandleToggleEnrollmentScreen() {
1190 delegate_->ShowEnterpriseEnrollmentScreen();
1193 void SigninScreenHandler::HandleToggleKioskEnableScreen() {
1194 policy::BrowserPolicyConnectorChromeOS* connector =
1195 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1197 !auto_enrollment_progress_subscription_ &&
1198 !connector->IsEnterpriseManaged() &&
1199 LoginDisplayHostImpl::default_host()) {
1200 AutoEnrollmentController* auto_enrollment_controller =
1201 LoginDisplayHostImpl::default_host()->GetAutoEnrollmentController();
1202 auto_enrollment_progress_subscription_ =
1203 auto_enrollment_controller->RegisterProgressCallback(
1204 base::Bind(&SigninScreenHandler::ContinueKioskEnableFlow,
1205 weak_factory_.GetWeakPtr()));
1206 ContinueKioskEnableFlow(auto_enrollment_controller->state());
1210 void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() {
1211 policy::BrowserPolicyConnectorChromeOS* connector =
1212 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1213 if (delegate_ && !connector->IsEnterpriseManaged())
1214 delegate_->ShowKioskAutolaunchScreen();
1217 void SigninScreenHandler::LoadUsers(const base::ListValue& users_list,
1219 CallJS("login.AccountPickerScreen.loadUsers",
1221 delegate_->IsShowGuest());
1224 void SigninScreenHandler::HandleAccountPickerReady() {
1225 VLOG(0) << "Login WebUI >> AccountPickerReady";
1227 if (delegate_ && !ScreenLocker::default_screen_locker() &&
1228 !chromeos::IsMachineHWIDCorrect() &&
1230 delegate_->ShowWrongHWIDScreen();
1234 PrefService* prefs = g_browser_process->local_state();
1235 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
1236 if (core_oobe_actor_) {
1237 core_oobe_actor_->ShowDeviceResetScreen();
1242 is_account_picker_showing_first_time_ = true;
1243 gaia_screen_handler_->MaybePreloadAuthExtension();
1245 ScreenlockBridge::Get()->SetLockHandler(this);
1246 if (ScreenLocker::default_screen_locker()) {
1247 ScreenLocker::default_screen_locker()->delegate()->OnLockWebUIReady();
1251 delegate_->OnSigninScreenReady();
1254 void SigninScreenHandler::HandleWallpaperReady() {
1255 if (ScreenLocker::default_screen_locker()) {
1256 ScreenLocker::default_screen_locker()->delegate()->
1257 OnLockBackgroundDisplayed();
1261 void SigninScreenHandler::HandleSignOutUser() {
1263 delegate_->Signout();
1266 void SigninScreenHandler::HandleCreateAccount() {
1268 delegate_->CreateAccount();
1271 void SigninScreenHandler::HandleOpenProxySettings() {
1272 LoginDisplayHostImpl::default_host()->OpenProxySettings();
1275 void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
1276 VLOG(1) << "Login WebUI >> loginVisible, src: " << source << ", "
1277 << "webui_visible_: " << webui_visible_;
1278 if (!webui_visible_) {
1279 // There might be multiple messages from OOBE UI so send notifications after
1280 // the first one only.
1281 content::NotificationService::current()->Notify(
1282 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
1283 content::NotificationService::AllSources(),
1284 content::NotificationService::NoDetails());
1285 TRACE_EVENT_ASYNC_END0(
1286 "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid);
1288 webui_visible_ = true;
1289 if (preferences_changed_delayed_)
1290 OnPreferencesChanged();
1293 void SigninScreenHandler::HandleCancelPasswordChangedFlow() {
1294 gaia_screen_handler_->StartClearingCookies(
1295 base::Bind(&SigninScreenHandler::CancelPasswordChangedFlowInternal,
1296 weak_factory_.GetWeakPtr()));
1299 void SigninScreenHandler::HandleCancelUserAdding() {
1301 delegate_->CancelUserAdding();
1304 void SigninScreenHandler::HandleMigrateUserData(
1305 const std::string& old_password) {
1307 delegate_->MigrateUserData(old_password);
1310 void SigninScreenHandler::HandleResyncUserData() {
1312 delegate_->ResyncUserData();
1315 void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source,
1317 VLOG(0) << "Login WebUI >> active: " << new_value << ", "
1318 << "source: " << source;
1320 if (source == "gaia-signin" && !new_value)
1321 gaia_screen_handler_->CancelEmbeddedSignin();
1323 if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() &&
1324 KioskAppManager::Get()->IsAutoLaunchRequested()) {
1325 VLOG(0) << "Showing auto-launch warning";
1326 // On slow devices, the wallpaper animation is not shown initially, so we
1327 // must explicitly load the wallpaper. This is also the case for the
1328 // account-picker and gaia-signin UI states.
1329 delegate_->LoadSigninWallpaper();
1330 HandleToggleKioskAutolaunchScreen();
1334 if (source == kSourceGaiaSignin) {
1335 ui_state_ = UI_STATE_GAIA_SIGNIN;
1336 } else if (source == kSourceAccountPicker) {
1337 ui_state_ = UI_STATE_ACCOUNT_PICKER;
1344 void SigninScreenHandler::HandleUnlockOnLoginSuccess() {
1345 DCHECK(user_manager::UserManager::Get()->IsUserLoggedIn());
1346 if (ScreenLocker::default_screen_locker())
1347 ScreenLocker::default_screen_locker()->UnlockOnLoginSuccess();
1350 void SigninScreenHandler::HandleShowLoadingTimeoutError() {
1351 UpdateState(ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
1354 void SigninScreenHandler::HandleUpdateOfflineLogin(bool offline_login_active) {
1355 offline_login_active_ = offline_login_active;
1358 void SigninScreenHandler::HandleFocusPod(const std::string& user_id) {
1359 SetUserInputMethod(user_id, ime_state_.get());
1360 #if !defined(USE_ATHENA)
1361 // TODO(dpolukhin): crbug.com/408734.
1362 WallpaperManager::Get()->SetUserWallpaperDelayed(user_id);
1364 ScreenlockBridge::Get()->SetFocusedUser(user_id);
1365 if (!test_focus_pod_callback_.is_null())
1366 test_focus_pod_callback_.Run();
1369 void SigninScreenHandler::HandleHardlockPod(const std::string& user_id) {
1370 SetAuthType(user_id,
1371 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
1373 EasyUnlockService* service = GetEasyUnlockServiceForUser(user_id);
1376 service->SetHardlockState(EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
1379 void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
1380 const std::string& user_id,
1381 const std::string& locale) {
1382 GetKeyboardLayoutsForLocale(
1383 base::Bind(&SigninScreenHandler::SendPublicSessionKeyboardLayouts,
1384 weak_factory_.GetWeakPtr(),
1390 void SigninScreenHandler::SendPublicSessionKeyboardLayouts(
1391 const std::string& user_id,
1392 const std::string& locale,
1393 scoped_ptr<base::ListValue> keyboard_layouts) {
1394 CallJS("login.AccountPickerScreen.setPublicSessionKeyboardLayouts",
1400 void SigninScreenHandler::HandleLaunchKioskApp(const std::string& app_id,
1401 bool diagnostic_mode) {
1402 UserContext context(user_manager::USER_TYPE_KIOSK_APP, app_id);
1403 SigninSpecifics specifics;
1404 specifics.kiosk_diagnostic_mode = diagnostic_mode;
1406 delegate_->Login(context, specifics);
1409 void SigninScreenHandler::HandleCancelConsumerManagementEnrollment() {
1410 policy::ConsumerManagementService* consumer_management =
1411 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
1412 GetConsumerManagementService();
1413 CHECK(consumer_management);
1414 consumer_management->SetEnrollmentStage(
1415 policy::ConsumerManagementService::ENROLLMENT_STAGE_CANCELED);
1416 is_enrolling_consumer_management_ = false;
1420 void SigninScreenHandler::HandleGetTouchViewState() {
1421 #if defined(USE_ATHENA)
1422 // Login UI should treat athena builds as if it's TouchView mode.
1423 CallJS("login.AccountPickerScreen.setTouchViewState", true);
1425 if (max_mode_delegate_) {
1426 CallJS("login.AccountPickerScreen.setTouchViewState",
1427 max_mode_delegate_->IsMaximizeModeEnabled());
1432 void SigninScreenHandler::HandleSwitchToEmbeddedSignin() {
1433 gaia_screen_handler_->SwitchToEmbeddedSignin();
1436 bool SigninScreenHandler::AllWhitelistedUsersPresent() {
1437 CrosSettings* cros_settings = CrosSettings::Get();
1438 bool allow_new_user = false;
1439 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
1442 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1443 const user_manager::UserList& users = user_manager->GetUsers();
1444 if (!delegate_ || users.size() > kMaxUsers) {
1447 const base::ListValue* whitelist = NULL;
1448 if (!cros_settings->GetList(kAccountsPrefUsers, &whitelist) || !whitelist)
1450 for (size_t i = 0; i < whitelist->GetSize(); ++i) {
1451 std::string whitelisted_user;
1452 // NB: Wildcards in the whitelist are also detected as not present here.
1453 if (!whitelist->GetString(i, &whitelisted_user) ||
1454 !user_manager->IsKnownUser(whitelisted_user)) {
1461 void SigninScreenHandler::CancelPasswordChangedFlowInternal() {
1464 delegate_->CancelPasswordChangedFlow();
1468 OobeUI* SigninScreenHandler::GetOobeUI() const {
1469 return static_cast<OobeUI*>(web_ui()->GetController());
1472 EasyUnlockService* SigninScreenHandler::GetEasyUnlockServiceForUser(
1473 const std::string& username) const {
1474 if (!ScreenLocker::default_screen_locker() &&
1475 GetOobeUI()->display_type() != OobeUI::kLoginDisplay)
1478 const user_manager::User* unlock_user = NULL;
1479 const user_manager::UserList& users = delegate_->GetUsers();
1480 for (user_manager::UserList::const_iterator it = users.begin();
1483 if ((*it)->email() == username) {
1491 ProfileHelper* profile_helper = ProfileHelper::Get();
1492 Profile* profile = profile_helper->GetProfileByUser(unlock_user);
1494 // The user profile should exists if and only if this is lock screen.
1495 DCHECK_NE(!profile, !ScreenLocker::default_screen_locker());
1498 profile = profile_helper->GetSigninProfile();
1500 return EasyUnlockService::Get(profile);
1503 OobeUI::Screen SigninScreenHandler::GetCurrentScreen() const {
1504 OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
1505 OobeUI* oobe_ui = GetOobeUI();
1507 screen = oobe_ui->current_screen();
1511 bool SigninScreenHandler::IsGaiaVisible() const {
1512 return IsSigninScreen(GetCurrentScreen()) &&
1513 ui_state_ == UI_STATE_GAIA_SIGNIN;
1516 bool SigninScreenHandler::IsGaiaHiddenByError() const {
1517 return IsSigninScreenHiddenByError() &&
1518 ui_state_ == UI_STATE_GAIA_SIGNIN;
1521 bool SigninScreenHandler::IsSigninScreenHiddenByError() const {
1522 return (GetCurrentScreen() == OobeUI::SCREEN_ERROR_MESSAGE) &&
1523 (IsSigninScreen(error_screen_actor_->parent_screen()));
1526 bool SigninScreenHandler::IsGuestSigninAllowed() const {
1527 CrosSettings* cros_settings = CrosSettings::Get();
1531 cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
1535 bool SigninScreenHandler::IsOfflineLoginAllowed() const {
1536 CrosSettings* cros_settings = CrosSettings::Get();
1540 // Offline login is allowed only when user pods are hidden.
1542 cros_settings->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_pods);
1546 void SigninScreenHandler::ContinueKioskEnableFlow(
1547 policy::AutoEnrollmentState state) {
1548 // Do not proceed with kiosk enable when auto enroll will be enforced.
1549 // TODO(xiyuan): Add an error UI feedkback so user knows what happens.
1551 case policy::AUTO_ENROLLMENT_STATE_IDLE:
1552 case policy::AUTO_ENROLLMENT_STATE_PENDING:
1553 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR:
1554 // Wait for the next callback.
1556 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT:
1557 // Auto-enrollment is on.
1558 LOG(WARNING) << "Kiosk enable flow aborted because auto enrollment is "
1559 "going to be enforced.";
1560 if (!kiosk_enable_flow_aborted_callback_for_test_.is_null())
1561 kiosk_enable_flow_aborted_callback_for_test_.Run();
1563 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR:
1564 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT:
1565 // Auto-enrollment not applicable.
1567 delegate_->ShowKioskEnableScreen();
1570 auto_enrollment_progress_subscription_.reset();
1573 void SigninScreenHandler::OnShowAddUser() {
1574 is_account_picker_showing_first_time_ = false;
1575 DCHECK(gaia_screen_handler_);
1576 gaia_screen_handler_->ShowGaia(is_enrolling_consumer_management_);
1579 GaiaScreenHandler::FrameState SigninScreenHandler::FrameState() const {
1580 DCHECK(gaia_screen_handler_);
1581 return gaia_screen_handler_->frame_state();
1584 net::Error SigninScreenHandler::FrameError() const {
1585 DCHECK(gaia_screen_handler_);
1586 return gaia_screen_handler_->frame_error();
1589 void SigninScreenHandler::OnCapsLockChanged(bool enabled) {
1590 caps_lock_enabled_ = enabled;
1591 if (page_is_ready())
1592 CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_);
1595 } // namespace chromeos