signin_screen_handler.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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. 4 5#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" 6 7#include <algorithm> 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/command_line.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 "chrome/browser/browser_process.h" 24#include "chrome/browser/browser_process_platform_part_chromeos.h" 25#include "chrome/browser/browser_shutdown.h" 26#include "chrome/browser/chrome_notification_types.h" 27#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" 28#include "chrome/browser/chromeos/boot_times_loader.h" 29#include "chrome/browser/chromeos/input_method/input_method_util.h" 30#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" 31#include "chrome/browser/chromeos/login/hwid_checker.h" 32#include "chrome/browser/chromeos/login/login_display_host.h" 33#include "chrome/browser/chromeos/login/login_display_host_impl.h" 34#include "chrome/browser/chromeos/login/multi_profile_user_controller.h" 35#include "chrome/browser/chromeos/login/screen_locker.h" 36#include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" 37#include "chrome/browser/chromeos/login/user.h" 38#include "chrome/browser/chromeos/login/wallpaper_manager.h" 39#include "chrome/browser/chromeos/login/webui_login_display.h" 40#include "chrome/browser/chromeos/login/wizard_controller.h" 41#include "chrome/browser/chromeos/net/network_portal_detector.h" 42#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 43#include "chrome/browser/chromeos/profiles/profile_helper.h" 44#include "chrome/browser/chromeos/settings/cros_settings.h" 45#include "chrome/browser/io_thread.h" 46#include "chrome/browser/profiles/profile.h" 47#include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h" 48#include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h" 49#include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h" 50#include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h" 51#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 52#include "chrome/common/chrome_switches.h" 53#include "chrome/common/pref_names.h" 54#include "chrome/common/url_constants.h" 55#include "chromeos/chromeos_switches.h" 56#include "chromeos/dbus/dbus_thread_manager.h" 57#include "chromeos/dbus/power_manager_client.h" 58#include "chromeos/ime/input_method_manager.h" 59#include "chromeos/ime/xkeyboard.h" 60#include "chromeos/network/network_state.h" 61#include "chromeos/network/network_state_handler.h" 62#include "content/public/browser/browser_thread.h" 63#include "content/public/browser/render_frame_host.h" 64#include "content/public/browser/web_contents.h" 65#include "google_apis/gaia/gaia_auth_util.h" 66#include "grit/chromium_strings.h" 67#include "grit/generated_resources.h" 68#include "net/url_request/url_request_context_getter.h" 69#include "third_party/cros_system_api/dbus/service_constants.h" 70 71#if defined(USE_AURA) 72#include "ash/shell.h" 73#include "ash/wm/lock_state_controller.h" 74#endif 75 76using content::BrowserThread; 77 78namespace { 79 80// User dictionary keys. 81const char kKeyUsername[] = "username"; 82const char kKeyDisplayName[] = "displayName"; 83const char kKeyEmailAddress[] = "emailAddress"; 84const char kKeyEnterpriseDomain[] = "enterpriseDomain"; 85const char kKeyPublicAccount[] = "publicAccount"; 86const char kKeyLocallyManagedUser[] = "locallyManagedUser"; 87const char kKeySignedIn[] = "signedIn"; 88const char kKeyCanRemove[] = "canRemove"; 89const char kKeyIsOwner[] = "isOwner"; 90const char kKeyInitialAuthType[] = "initialAuthType"; 91const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed"; 92const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy"; 93 94// Max number of users to show. 95const size_t kMaxUsers = 18; 96 97// Timeout to delay first notification about offline state for a 98// current network. 99const int kOfflineTimeoutSec = 5; 100 101// Timeout used to prevent infinite connecting to a flaky network. 102const int kConnectingTimeoutSec = 60; 103 104// Type of the login screen UI that is currently presented to user. 105const char kSourceGaiaSignin[] = "gaia-signin"; 106const char kSourceAccountPicker[] = "account-picker"; 107 108// The Task posted to PostTaskAndReply in StartClearingDnsCache on the IO 109// thread. 110void ClearDnsCache(IOThread* io_thread) { 111 DCHECK_CURRENTLY_ON(BrowserThread::IO); 112 if (browser_shutdown::IsTryingToQuit()) 113 return; 114 115 io_thread->ClearHostCache(); 116} 117 118static bool Contains(const std::vector<std::string>& container, 119 const std::string& value) { 120 return std::find(container.begin(), container.end(), value) != 121 container.end(); 122} 123 124} // namespace 125 126namespace chromeos { 127 128namespace { 129 130bool IsOnline(NetworkStateInformer::State state, 131 ErrorScreenActor::ErrorReason reason) { 132 return state == NetworkStateInformer::ONLINE && 133 reason != ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED && 134 reason != ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT; 135} 136 137bool IsBehindCaptivePortal(NetworkStateInformer::State state, 138 ErrorScreenActor::ErrorReason reason) { 139 return state == NetworkStateInformer::CAPTIVE_PORTAL || 140 reason == ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED; 141} 142 143bool IsProxyError(NetworkStateInformer::State state, 144 ErrorScreenActor::ErrorReason reason, 145 net::Error frame_error) { 146 return state == NetworkStateInformer::PROXY_AUTH_REQUIRED || 147 reason == ErrorScreenActor::ERROR_REASON_PROXY_AUTH_CANCELLED || 148 reason == ErrorScreenActor::ERROR_REASON_PROXY_CONNECTION_FAILED || 149 (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR && 150 (frame_error == net::ERR_PROXY_CONNECTION_FAILED || 151 frame_error == net::ERR_TUNNEL_CONNECTION_FAILED)); 152} 153 154bool IsSigninScreen(const OobeUI::Screen screen) { 155 return screen == OobeUI::SCREEN_GAIA_SIGNIN || 156 screen == OobeUI::SCREEN_ACCOUNT_PICKER; 157} 158 159bool IsSigninScreenError(ErrorScreen::ErrorState error_state) { 160 return error_state == ErrorScreen::ERROR_STATE_PORTAL || 161 error_state == ErrorScreen::ERROR_STATE_OFFLINE || 162 error_state == ErrorScreen::ERROR_STATE_PROXY || 163 error_state == ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT; 164} 165 166// Returns network name by service path. 167std::string GetNetworkName(const std::string& service_path) { 168 const NetworkState* network = NetworkHandler::Get()->network_state_handler()-> 169 GetNetworkState(service_path); 170 if (!network) 171 return std::string(); 172 return network->name(); 173} 174 175static bool SetUserInputMethodImpl( 176 const std::string& username, 177 chromeos::input_method::InputMethodManager* manager) { 178 PrefService* const local_state = g_browser_process->local_state(); 179 180 const base::DictionaryValue* users_lru_input_methods = 181 local_state->GetDictionary(prefs::kUsersLRUInputMethod); 182 183 if (users_lru_input_methods == NULL) { 184 DLOG(WARNING) << "SetUserInputMethod('" << username 185 << "'): no kUsersLRUInputMethod"; 186 return false; 187 } 188 189 std::string input_method; 190 191 if (!users_lru_input_methods->GetStringWithoutPathExpansion(username, 192 &input_method)) { 193 DVLOG(0) << "SetUserInputMethod('" << username 194 << "'): no input method for this user"; 195 return false; 196 } 197 198 if (input_method.empty()) 199 return false; 200 201 if (!manager->IsLoginKeyboard(input_method)) { 202 LOG(WARNING) << "SetUserInputMethod('" << username 203 << "'): stored user LRU input method '" << input_method 204 << "' is no longer Full Latin Keyboard Language" 205 << " (entry dropped). Use hardware default instead."; 206 207 DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod); 208 209 base::DictionaryValue* const users_lru_input_methods = updater.Get(); 210 if (users_lru_input_methods != NULL) { 211 users_lru_input_methods->SetStringWithoutPathExpansion(username, ""); 212 } 213 return false; 214 } 215 216 if (!Contains(manager->GetActiveInputMethodIds(), input_method)) { 217 if (!manager->EnableInputMethod(input_method)) { 218 DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username 219 << "'): user input method '" << input_method 220 << "' is not enabled and enabling failed (ignored!)."; 221 } 222 } 223 manager->ChangeInputMethod(input_method); 224 225 return true; 226} 227 228void RecordSAMLScrapingVerificationResultInHistogram(bool success) { 229 UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.Scraping.VerificationResult", success); 230} 231 232bool ShouldForceOnlineSignIn(const User* user) { 233 // Public sessions are always allowed to log in offline. 234 // Supervised user are allowed to log in offline if their OAuth token status 235 // is unknown or valid. 236 // For all other users, force online sign in if: 237 // * The flag to force online sign-in is set for the user. 238 // * The user's OAuth token is invalid. 239 // * The user's OAuth token status is unknown (except supervised users, 240 // see above). 241 if (user->is_logged_in()) 242 return false; 243 244 const User::OAuthTokenStatus token_status = user->oauth_token_status(); 245 const bool is_locally_managed_user = 246 user->GetType() == User::USER_TYPE_LOCALLY_MANAGED; 247 const bool is_public_session = 248 user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT; 249 250 if (is_locally_managed_user && 251 token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN) { 252 return false; 253 } 254 255 if (is_public_session) 256 return false; 257 258 return user->force_online_signin() || 259 (token_status == User::OAUTH2_TOKEN_STATUS_INVALID) || 260 (token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN); 261} 262 263} // namespace 264 265// LoginScreenContext implementation ------------------------------------------ 266 267LoginScreenContext::LoginScreenContext() { 268 Init(); 269} 270 271LoginScreenContext::LoginScreenContext(const base::ListValue* args) { 272 Init(); 273 274 if (!args || args->GetSize() == 0) 275 return; 276 std::string email; 277 if (args->GetString(0, &email)) 278 email_ = email; 279} 280 281void LoginScreenContext::Init() { 282 oobe_ui_ = false; 283} 284 285// SigninScreenHandler implementation ------------------------------------------ 286 287SigninScreenHandler::SigninScreenHandler( 288 const scoped_refptr<NetworkStateInformer>& network_state_informer, 289 ErrorScreenActor* error_screen_actor, 290 CoreOobeActor* core_oobe_actor, 291 GaiaScreenHandler* gaia_screen_handler) 292 : ui_state_(UI_STATE_UNKNOWN), 293 delegate_(NULL), 294 native_window_delegate_(NULL), 295 show_on_init_(false), 296 oobe_ui_(false), 297 gaia_silent_load_(false), 298 is_account_picker_showing_first_time_(false), 299 dns_cleared_(false), 300 dns_clear_task_running_(false), 301 cookies_cleared_(false), 302 network_state_informer_(network_state_informer), 303 using_saml_api_(false), 304 test_expects_complete_login_(false), 305 weak_factory_(this), 306 webui_visible_(false), 307 preferences_changed_delayed_(false), 308 error_screen_actor_(error_screen_actor), 309 core_oobe_actor_(core_oobe_actor), 310 is_first_update_state_call_(true), 311 offline_login_active_(false), 312 last_network_state_(NetworkStateInformer::UNKNOWN), 313 has_pending_auth_ui_(false), 314 caps_lock_enabled_(false), 315 gaia_screen_handler_(gaia_screen_handler) { 316 DCHECK(network_state_informer_.get()); 317 DCHECK(error_screen_actor_); 318 DCHECK(core_oobe_actor_); 319 DCHECK(gaia_screen_handler_); 320 gaia_screen_handler_->SetSigninScreenHandler(this); 321 network_state_informer_->AddObserver(this); 322 allow_new_user_subscription_ = CrosSettings::Get()->AddSettingsObserver( 323 kAccountsPrefAllowNewUser, 324 base::Bind(&SigninScreenHandler::UserSettingsChanged, 325 base::Unretained(this))); 326 allow_guest_subscription_ = CrosSettings::Get()->AddSettingsObserver( 327 kAccountsPrefAllowGuest, 328 base::Bind(&SigninScreenHandler::UserSettingsChanged, 329 base::Unretained(this))); 330 331 registrar_.Add(this, 332 chrome::NOTIFICATION_AUTH_NEEDED, 333 content::NotificationService::AllSources()); 334 registrar_.Add(this, 335 chrome::NOTIFICATION_AUTH_SUPPLIED, 336 content::NotificationService::AllSources()); 337 registrar_.Add(this, 338 chrome::NOTIFICATION_AUTH_CANCELLED, 339 content::NotificationService::AllSources()); 340} 341 342SigninScreenHandler::~SigninScreenHandler() { 343 ash::Shell::GetInstance()->RemovePreTargetHandler(this); 344 weak_factory_.InvalidateWeakPtrs(); 345 if (delegate_) 346 delegate_->SetWebUIHandler(NULL); 347 network_state_informer_->RemoveObserver(this); 348} 349 350void SigninScreenHandler::DeclareLocalizedValues( 351 LocalizedValuesBuilder* builder) { 352 builder->Add("passwordHint", IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT); 353 builder->Add("podMenuButtonAccessibleName", 354 IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME); 355 builder->Add("podMenuRemoveItemAccessibleName", 356 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME); 357 builder->Add("passwordFieldAccessibleName", 358 IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME); 359 builder->Add("signedIn", IDS_SCREEN_LOCK_ACTIVE_USER); 360 builder->Add("signinButton", IDS_LOGIN_BUTTON); 361 builder->Add("launchAppButton", IDS_LAUNCH_APP_BUTTON); 362 builder->Add("shutDown", IDS_SHUTDOWN_BUTTON); 363 builder->Add("addUser", IDS_ADD_USER_BUTTON); 364 builder->Add("browseAsGuest", IDS_GO_INCOGNITO_BUTTON); 365 builder->Add("cancel", IDS_CANCEL); 366 builder->Add("signOutUser", IDS_SCREEN_LOCK_SIGN_OUT); 367 builder->Add("offlineLogin", IDS_OFFLINE_LOGIN_HTML); 368 builder->Add("ownerUserPattern", IDS_LOGIN_POD_OWNER_USER); 369 builder->Add("removeUser", IDS_LOGIN_POD_REMOVE_USER); 370 builder->Add("errorTpmFailureTitle", IDS_LOGIN_ERROR_TPM_FAILURE_TITLE); 371 builder->Add("errorTpmFailureReboot", IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT); 372 builder->Add("errorTpmFailureRebootButton", 373 IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT_BUTTON); 374 375 policy::BrowserPolicyConnectorChromeOS* connector = 376 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 377 builder->Add("disabledAddUserTooltip", 378 connector->IsEnterpriseManaged() 379 ? IDS_DISABLED_ADD_USER_TOOLTIP_ENTERPRISE 380 : IDS_DISABLED_ADD_USER_TOOLTIP); 381 382 builder->Add("supervisedUserExpiredTokenWarning", 383 IDS_SUPERVISED_USER_EXPIRED_TOKEN_WARNING); 384 builder->Add("signinBannerText", IDS_LOGIN_USER_ADDING_BANNER); 385 386 // Multi-profiles related strings. 387 builder->Add("multiProfilesRestrictedPolicyTitle", 388 IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE); 389 builder->Add("multiProfilesNotAllowedPolicyMsg", 390 IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG); 391 builder->Add("multiProfilesPrimaryOnlyPolicyMsg", 392 IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG); 393 394 // Strings used by password changed dialog. 395 builder->Add("passwordChangedTitle", IDS_LOGIN_PASSWORD_CHANGED_TITLE); 396 builder->Add("passwordChangedDesc", IDS_LOGIN_PASSWORD_CHANGED_DESC); 397 builder->AddF("passwordChangedMoreInfo", 398 IDS_LOGIN_PASSWORD_CHANGED_MORE_INFO, 399 IDS_SHORT_PRODUCT_OS_NAME); 400 401 builder->Add("oldPasswordHint", IDS_LOGIN_PASSWORD_CHANGED_OLD_PASSWORD_HINT); 402 builder->Add("oldPasswordIncorrect", 403 IDS_LOGIN_PASSWORD_CHANGED_INCORRECT_OLD_PASSWORD); 404 builder->Add("passwordChangedCantRemember", 405 IDS_LOGIN_PASSWORD_CHANGED_CANT_REMEMBER); 406 builder->Add("passwordChangedBackButton", 407 IDS_LOGIN_PASSWORD_CHANGED_BACK_BUTTON); 408 builder->Add("passwordChangedsOkButton", IDS_OK); 409 builder->Add("passwordChangedProceedAnyway", 410 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY); 411 builder->Add("proceedAnywayButton", 412 IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY_BUTTON); 413 builder->Add("publicAccountInfoFormat", IDS_LOGIN_PUBLIC_ACCOUNT_INFO_FORMAT); 414 builder->Add("publicAccountReminder", 415 IDS_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER); 416 builder->Add("publicAccountEnter", IDS_LOGIN_PUBLIC_ACCOUNT_ENTER); 417 builder->Add("publicAccountEnterAccessibleName", 418 IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME); 419 builder->AddF("removeUserWarningText", 420 IDS_LOGIN_POD_USER_REMOVE_WARNING, 421 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL)); 422 builder->Add("removeUserWarningButtonTitle", 423 IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON); 424 425 builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE); 426 427 builder->Add("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE); 428 builder->Add("confirmPasswordLabel", IDS_LOGIN_CONFIRM_PASSWORD_LABEL); 429 builder->Add("confirmPasswordConfirmButton", 430 IDS_LOGIN_CONFIRM_PASSWORD_CONFIRM_BUTTON); 431 builder->Add("confirmPasswordText", IDS_LOGIN_CONFIRM_PASSWORD_TEXT); 432 builder->Add("confirmPasswordErrorText", 433 IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT); 434 builder->Add("easyUnlockTooltip", 435 IDS_LOGIN_EASY_UNLOCK_TOOLTIP); 436 437 builder->Add("fatalEnrollmentError", 438 IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR); 439 440 if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) 441 builder->Add("demoLoginMessage", IDS_KIOSK_MODE_LOGIN_MESSAGE); 442 443 builder->Add("runType", CommandLine::ForCurrentProcess()->HasSwitch( 444 switches::kFirstExecAfterBoot) ? "firstExecAfterBoot" : 445 "notFirstExecAfterBoot"); 446} 447 448void SigninScreenHandler::Show(const LoginScreenContext& context) { 449 CHECK(delegate_); 450 451 // Just initialize internal fields from context and call ShowImpl(). 452 oobe_ui_ = context.oobe_ui(); 453 if (!context.email().empty()) 454 email_ = context.email(); 455 else 456 email_.clear(); 457 ShowImpl(); 458} 459 460void SigninScreenHandler::ShowRetailModeLoginSpinner() { 461 CallJS("showLoginSpinner"); 462} 463 464void SigninScreenHandler::SetDelegate(SigninScreenHandlerDelegate* delegate) { 465 delegate_ = delegate; 466 if (delegate_) 467 delegate_->SetWebUIHandler(this); 468 else 469 auto_enrollment_progress_subscription_.reset(); 470} 471 472void SigninScreenHandler::SetNativeWindowDelegate( 473 NativeWindowDelegate* native_window_delegate) { 474 native_window_delegate_ = native_window_delegate; 475} 476 477void SigninScreenHandler::OnNetworkReady() { 478 LOG(WARNING) << "OnNetworkReady() call."; 479 MaybePreloadAuthExtension(); 480} 481 482void SigninScreenHandler::UpdateState(ErrorScreenActor::ErrorReason reason) { 483 UpdateStateInternal(reason, false); 484} 485 486// SigninScreenHandler, private: ----------------------------------------------- 487 488void SigninScreenHandler::ShowImpl() { 489 if (!page_is_ready()) { 490 show_on_init_ = true; 491 return; 492 } 493 494 if (oobe_ui_) { 495 // Shows new user sign-in for OOBE. 496 OnShowAddUser(email_); 497 } else { 498 // Populates account picker. Animation is turned off for now until we 499 // figure out how to make it fast enough. 500 SendUserList(false); 501 502 // Reset Caps Lock state when login screen is shown. 503 input_method::InputMethodManager::Get()->GetXKeyboard()-> 504 SetCapsLockEnabled(false); 505 506 base::DictionaryValue params; 507 params.SetBoolean("disableAddUser", AllWhitelistedUsersPresent()); 508 UpdateUIState(UI_STATE_ACCOUNT_PICKER, ¶ms); 509 } 510} 511 512void SigninScreenHandler::UpdateUIState(UIState ui_state, 513 base::DictionaryValue* params) { 514 switch (ui_state) { 515 case UI_STATE_GAIA_SIGNIN: 516 ui_state_ = UI_STATE_GAIA_SIGNIN; 517 ShowScreen(OobeUI::kScreenGaiaSignin, params); 518 break; 519 case UI_STATE_ACCOUNT_PICKER: 520 ui_state_ = UI_STATE_ACCOUNT_PICKER; 521 ShowScreen(OobeUI::kScreenAccountPicker, params); 522 break; 523 default: 524 NOTREACHED(); 525 break; 526 } 527} 528 529// TODO (ygorshenin@): split this method into small parts. 530// TODO (ygorshenin@): move this logic to GaiaScreenHandler. 531void SigninScreenHandler::UpdateStateInternal( 532 ErrorScreenActor::ErrorReason reason, 533 bool force_update) { 534 // Do nothing once user has signed in or sign in is in progress. 535 // TODO(ygorshenin): We will end up here when processing network state 536 // notification but no ShowSigninScreen() was called so delegate_ will be 537 // NULL. Network state processing logic does not belong here. 538 if (delegate_ && 539 (delegate_->IsUserSigninCompleted() || delegate_->IsSigninInProgress())) { 540 return; 541 } 542 543 NetworkStateInformer::State state = network_state_informer_->state(); 544 const std::string network_path = network_state_informer_->network_path(); 545 const std::string network_name = GetNetworkName(network_path); 546 547 // Skip "update" notification about OFFLINE state from 548 // NetworkStateInformer if previous notification already was 549 // delayed. 550 if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) && 551 !force_update && !update_state_closure_.IsCancelled()) { 552 return; 553 } 554 555 // TODO (ygorshenin@): switch log level to INFO once signin screen 556 // will be tested well. 557 LOG(WARNING) << "SigninScreenHandler::UpdateStateInternal(): " 558 << "state=" << NetworkStateInformer::StatusString(state) << ", " 559 << "network_name=" << network_name << ", " 560 << "reason=" << ErrorScreenActor::ErrorReasonString(reason) 561 << ", force_update=" << force_update; 562 update_state_closure_.Cancel(); 563 564 if ((state == NetworkStateInformer::OFFLINE && !force_update) || 565 has_pending_auth_ui_) { 566 update_state_closure_.Reset( 567 base::Bind(&SigninScreenHandler::UpdateStateInternal, 568 weak_factory_.GetWeakPtr(), 569 reason, 570 true)); 571 base::MessageLoop::current()->PostDelayedTask( 572 FROM_HERE, 573 update_state_closure_.callback(), 574 base::TimeDelta::FromSeconds(kOfflineTimeoutSec)); 575 return; 576 } 577 578 // Don't show or hide error screen if we're in connecting state. 579 if (state == NetworkStateInformer::CONNECTING && !force_update) { 580 if (connecting_closure_.IsCancelled()) { 581 // First notification about CONNECTING state. 582 connecting_closure_.Reset( 583 base::Bind(&SigninScreenHandler::UpdateStateInternal, 584 weak_factory_.GetWeakPtr(), 585 reason, 586 true)); 587 base::MessageLoop::current()->PostDelayedTask( 588 FROM_HERE, 589 connecting_closure_.callback(), 590 base::TimeDelta::FromSeconds(kConnectingTimeoutSec)); 591 } 592 return; 593 } 594 connecting_closure_.Cancel(); 595 596 const bool is_online = IsOnline(state, reason); 597 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason); 598 const bool is_gaia_loading_timeout = 599 (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT); 600 const bool is_gaia_error = 601 FrameError() != net::OK && FrameError() != net::ERR_NETWORK_CHANGED; 602 const bool is_gaia_signin = IsGaiaVisible() || IsGaiaHiddenByError(); 603 const bool error_screen_should_overlay = 604 !offline_login_active_ && IsGaiaVisible(); 605 const bool from_not_online_to_online_transition = 606 is_online && last_network_state_ != NetworkStateInformer::ONLINE; 607 last_network_state_ = state; 608 609 if (is_online || !is_behind_captive_portal) 610 error_screen_actor_->HideCaptivePortal(); 611 612 // Hide offline message (if needed) and return if current screen is 613 // not a Gaia frame. 614 if (!is_gaia_signin) { 615 if (!IsSigninScreenHiddenByError()) 616 HideOfflineMessage(state, reason); 617 return; 618 } 619 620 // Reload frame if network state is changed from {!ONLINE} -> ONLINE state. 621 if (reason == ErrorScreenActor::ERROR_REASON_NETWORK_STATE_CHANGED && 622 from_not_online_to_online_transition) { 623 // Schedules a immediate retry. 624 LOG(WARNING) << "Retry page load since network has been changed."; 625 ReloadGaiaScreen(); 626 } 627 628 if (reason == ErrorScreenActor::ERROR_REASON_PROXY_CONFIG_CHANGED && 629 error_screen_should_overlay) { 630 // Schedules a immediate retry. 631 LOG(WARNING) << "Retry page load since proxy settings has been changed."; 632 ReloadGaiaScreen(); 633 } 634 635 if (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR && 636 !IsProxyError(state, reason, FrameError())) { 637 LOG(WARNING) << "Retry page load due to reason: " 638 << ErrorScreenActor::ErrorReasonString(reason); 639 ReloadGaiaScreen(); 640 } 641 642 if ((!is_online || is_gaia_loading_timeout || is_gaia_error) && 643 !offline_login_active_) { 644 SetupAndShowOfflineMessage(state, reason); 645 } else { 646 HideOfflineMessage(state, reason); 647 } 648} 649 650void SigninScreenHandler::SetupAndShowOfflineMessage( 651 NetworkStateInformer:: State state, 652 ErrorScreenActor::ErrorReason reason) { 653 const std::string network_path = network_state_informer_->network_path(); 654 const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason); 655 const bool is_proxy_error = IsProxyError(state, reason, FrameError()); 656 const bool is_gaia_loading_timeout = 657 (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT); 658 659 if (is_proxy_error) { 660 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PROXY, 661 std::string()); 662 } else if (is_behind_captive_portal) { 663 // Do not bother a user with obsessive captive portal showing. This 664 // check makes captive portal being shown only once: either when error 665 // screen is shown for the first time or when switching from another 666 // error screen (offline, proxy). 667 if (IsGaiaVisible() || 668 (error_screen_actor_->error_state() != 669 ErrorScreen::ERROR_STATE_PORTAL)) { 670 error_screen_actor_->FixCaptivePortal(); 671 } 672 const std::string network_name = GetNetworkName(network_path); 673 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PORTAL, 674 network_name); 675 } else if (is_gaia_loading_timeout) { 676 error_screen_actor_->SetErrorState( 677 ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT, std::string()); 678 } else { 679 error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE, 680 std::string()); 681 } 682 683 const bool guest_signin_allowed = IsGuestSigninAllowed() && 684 IsSigninScreenError(error_screen_actor_->error_state()); 685 error_screen_actor_->AllowGuestSignin(guest_signin_allowed); 686 687 const bool offline_login_allowed = IsOfflineLoginAllowed() && 688 IsSigninScreenError(error_screen_actor_->error_state()) && 689 error_screen_actor_->error_state() != 690 ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT; 691 error_screen_actor_->AllowOfflineLogin(offline_login_allowed); 692 693 if (GetCurrentScreen() != OobeUI::SCREEN_ERROR_MESSAGE) { 694 base::DictionaryValue params; 695 const std::string network_type = network_state_informer_->network_type(); 696 params.SetString("lastNetworkType", network_type); 697 error_screen_actor_->SetUIState(ErrorScreen::UI_STATE_SIGNIN); 698 error_screen_actor_->Show(OobeUI::SCREEN_GAIA_SIGNIN, ¶ms); 699 } 700} 701 702void SigninScreenHandler::HideOfflineMessage( 703 NetworkStateInformer::State state, 704 ErrorScreenActor::ErrorReason reason) { 705 if (!IsSigninScreenHiddenByError()) 706 return; 707 708 error_screen_actor_->Hide(); 709 710 // Forces a reload for Gaia screen on hiding error message. 711 if (IsGaiaVisible() || IsGaiaHiddenByError()) 712 ReloadGaiaScreen(); 713} 714 715void SigninScreenHandler::ReloadGaiaScreen() { 716 gaia_screen_handler_->ReloadGaia(); 717} 718 719void SigninScreenHandler::Initialize() { 720 // If delegate_ is NULL here (e.g. WebUIScreenLocker has been destroyed), 721 // don't do anything, just return. 722 if (!delegate_) 723 return; 724 725 // Make sure the event is processed by this before the IME. 726 ash::Shell::GetInstance()->PrependPreTargetHandler(this); 727 728 if (show_on_init_) { 729 show_on_init_ = false; 730 ShowImpl(); 731 } 732} 733 734gfx::NativeWindow SigninScreenHandler::GetNativeWindow() { 735 if (native_window_delegate_) 736 return native_window_delegate_->GetNativeWindow(); 737 return NULL; 738} 739 740void SigninScreenHandler::RegisterMessages() { 741 AddCallback("usingSAMLAPI", &SigninScreenHandler::HandleUsingSAMLAPI); 742 AddCallback("scrapedPasswordCount", 743 &SigninScreenHandler::HandleScrapedPasswordCount); 744 AddCallback("scrapedPasswordVerificationFailed", 745 &SigninScreenHandler::HandleScrapedPasswordVerificationFailed); 746 AddCallback("authenticateUser", &SigninScreenHandler::HandleAuthenticateUser); 747 AddCallback("completeLogin", &SigninScreenHandler::HandleCompleteLogin); 748 AddCallback("completeAuthentication", 749 &SigninScreenHandler::HandleCompleteAuthentication); 750 AddCallback("getUsers", &SigninScreenHandler::HandleGetUsers); 751 AddCallback("launchDemoUser", &SigninScreenHandler::HandleLaunchDemoUser); 752 AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito); 753 AddCallback("showLocallyManagedUserCreationScreen", 754 &SigninScreenHandler::HandleShowLocallyManagedUserCreationScreen); 755 AddCallback("launchPublicAccount", 756 &SigninScreenHandler::HandleLaunchPublicAccount); 757 AddRawCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin); 758 AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem); 759 AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser); 760 AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem); 761 AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper); 762 AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser); 763 AddCallback("toggleEnrollmentScreen", 764 &SigninScreenHandler::HandleToggleEnrollmentScreen); 765 AddCallback("toggleKioskEnableScreen", 766 &SigninScreenHandler::HandleToggleKioskEnableScreen); 767 AddCallback("toggleResetScreen", 768 &SigninScreenHandler::HandleToggleResetScreen); 769 AddCallback("createAccount", &SigninScreenHandler::HandleCreateAccount); 770 AddCallback("accountPickerReady", 771 &SigninScreenHandler::HandleAccountPickerReady); 772 AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady); 773 AddCallback("loginWebuiReady", &SigninScreenHandler::HandleLoginWebuiReady); 774 AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser); 775 AddCallback("networkErrorShown", 776 &SigninScreenHandler::HandleNetworkErrorShown); 777 AddCallback("openProxySettings", 778 &SigninScreenHandler::HandleOpenProxySettings); 779 AddCallback("loginVisible", &SigninScreenHandler::HandleLoginVisible); 780 AddCallback("cancelPasswordChangedFlow", 781 &SigninScreenHandler::HandleCancelPasswordChangedFlow); 782 AddCallback("cancelUserAdding", 783 &SigninScreenHandler::HandleCancelUserAdding); 784 AddCallback("migrateUserData", &SigninScreenHandler::HandleMigrateUserData); 785 AddCallback("resyncUserData", &SigninScreenHandler::HandleResyncUserData); 786 AddCallback("loginUIStateChanged", 787 &SigninScreenHandler::HandleLoginUIStateChanged); 788 AddCallback("unlockOnLoginSuccess", 789 &SigninScreenHandler::HandleUnlockOnLoginSuccess); 790 AddCallback("showLoadingTimeoutError", 791 &SigninScreenHandler::HandleShowLoadingTimeoutError); 792 AddCallback("updateOfflineLogin", 793 &SigninScreenHandler::HandleUpdateOfflineLogin); 794 AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod); 795 AddCallback("customButtonClicked", 796 &SigninScreenHandler::HandleCustomButtonClicked); 797 AddCallback("retrieveAuthenticatedUserEmail", 798 &SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail); 799 800 // This message is sent by the kiosk app menu, but is handled here 801 // so we can tell the delegate to launch the app. 802 AddCallback("launchKioskApp", &SigninScreenHandler::HandleLaunchKioskApp); 803} 804 805void SigninScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) { 806 registry->RegisterDictionaryPref(prefs::kUsersLRUInputMethod); 807} 808 809void SigninScreenHandler::HandleGetUsers() { 810 SendUserList(false); 811} 812 813void SigninScreenHandler::ClearAndEnablePassword() { 814 core_oobe_actor_->ResetSignInUI(false); 815} 816 817void SigninScreenHandler::ClearUserPodPassword() { 818 core_oobe_actor_->ClearUserPodPassword(); 819} 820 821void SigninScreenHandler::RefocusCurrentPod() { 822 core_oobe_actor_->RefocusCurrentPod(); 823} 824 825void SigninScreenHandler::OnLoginSuccess(const std::string& username) { 826 core_oobe_actor_->OnLoginSuccess(username); 827} 828 829void SigninScreenHandler::OnUserRemoved(const std::string& username) { 830 CallJS("login.AccountPickerScreen.removeUser", username); 831 if (delegate_->GetUsers().empty()) 832 OnShowAddUser(""); 833} 834 835void SigninScreenHandler::OnUserImageChanged(const User& user) { 836 if (page_is_ready()) 837 CallJS("login.AccountPickerScreen.updateUserImage", user.email()); 838} 839 840void SigninScreenHandler::OnPreferencesChanged() { 841 // Make sure that one of the login UI is fully functional now, otherwise 842 // preferences update would be picked up next time it will be shown. 843 if (!webui_visible_) { 844 LOG(WARNING) << "Login UI is not active - postponed prefs change."; 845 preferences_changed_delayed_ = true; 846 return; 847 } 848 849 if (delegate_ && !delegate_->IsShowUsers()) { 850 HandleShowAddUser(NULL); 851 } else { 852 SendUserList(false); 853 UpdateUIState(UI_STATE_ACCOUNT_PICKER, NULL); 854 } 855 preferences_changed_delayed_ = false; 856} 857 858void SigninScreenHandler::ResetSigninScreenHandlerDelegate() { 859 SetDelegate(NULL); 860} 861 862void SigninScreenHandler::ShowBannerMessage(const std::string& message) { 863 CallJS("login.AccountPickerScreen.showBannerMessage", message); 864} 865 866void SigninScreenHandler::ShowUserPodButton( 867 const std::string& username, 868 const std::string& iconURL, 869 const base::Closure& click_callback) { 870 user_pod_button_callback_map_[username] = click_callback; 871 CallJS("login.AccountPickerScreen.showUserPodButton", username, iconURL); 872 873 // TODO(tengs): Move this code once we move unlocking to native code. 874 if (ScreenLocker::default_screen_locker()) { 875 UserManager* user_manager = UserManager::Get(); 876 const User* user = user_manager->FindUser(username); 877 if (!user) 878 return; 879 PrefService* profile_prefs = 880 user_manager->GetProfileByUser(user)->GetPrefs(); 881 if (profile_prefs->GetBoolean(prefs::kEasyUnlockShowTutorial)) { 882 CallJS("login.AccountPickerScreen.showEasyUnlockBubble"); 883 profile_prefs->SetBoolean(prefs::kEasyUnlockShowTutorial, false); 884 } 885 } 886} 887 888void SigninScreenHandler::HideUserPodButton(const std::string& username) { 889 CallJS("login.AccountPickerScreen.hideUserPodButton", username); 890} 891 892void SigninScreenHandler::SetAuthType(const std::string& username, 893 LoginDisplay::AuthType auth_type, 894 const std::string& initial_value) { 895 user_auth_type_map_[username] = auth_type; 896 CallJS("login.AccountPickerScreen.setAuthType", 897 username, 898 static_cast<int>(auth_type), 899 base::StringValue(initial_value)); 900} 901 902LoginDisplay::AuthType SigninScreenHandler::GetAuthType( 903 const std::string& username) const { 904 if (user_auth_type_map_.find(username) == user_auth_type_map_.end()) 905 return LoginDisplay::OFFLINE_PASSWORD; 906 return user_auth_type_map_.find(username)->second; 907} 908 909void SigninScreenHandler::ShowError(int login_attempts, 910 const std::string& error_text, 911 const std::string& help_link_text, 912 HelpAppLauncher::HelpTopic help_topic_id) { 913 core_oobe_actor_->ShowSignInError(login_attempts, error_text, help_link_text, 914 help_topic_id); 915} 916 917void SigninScreenHandler::ShowErrorScreen(LoginDisplay::SigninError error_id) { 918 switch (error_id) { 919 case LoginDisplay::TPM_ERROR: 920 core_oobe_actor_->ShowTpmError(); 921 break; 922 default: 923 NOTREACHED() << "Unknown sign in error"; 924 break; 925 } 926} 927 928void SigninScreenHandler::ShowSigninUI(const std::string& email) { 929 core_oobe_actor_->ShowSignInUI(email); 930} 931 932void SigninScreenHandler::ShowGaiaPasswordChanged(const std::string& username) { 933 email_ = username; 934 password_changed_for_.insert(email_); 935 core_oobe_actor_->ShowSignInUI(email_); 936 CallJS("login.setAuthType", 937 username, 938 static_cast<int>(LoginDisplay::ONLINE_SIGN_IN), 939 base::StringValue("")); 940} 941 942void SigninScreenHandler::ShowPasswordChangedDialog(bool show_password_error) { 943 core_oobe_actor_->ShowPasswordChangedScreen(show_password_error); 944} 945 946void SigninScreenHandler::ShowSigninScreenForCreds( 947 const std::string& username, 948 const std::string& password) { 949 VLOG(2) << "ShowSigninScreenForCreds for user " << username 950 << ", frame_state=" << FrameState(); 951 952 test_user_ = username; 953 test_pass_ = password; 954 test_expects_complete_login_ = true; 955 956 // Submit login form for test if gaia is ready. If gaia is loading, login 957 // will be attempted in HandleLoginWebuiReady after gaia is ready. Otherwise, 958 // reload gaia then follow the loading case. 959 if (FrameState() == GaiaScreenHandler::FRAME_STATE_LOADED) 960 SubmitLoginFormForTest(); 961 else if (FrameState() != GaiaScreenHandler::FRAME_STATE_LOADING) 962 HandleShowAddUser(NULL); 963} 964 965void SigninScreenHandler::OnCookiesCleared(base::Closure on_clear_callback) { 966 DCHECK_CURRENTLY_ON(BrowserThread::UI); 967 cookies_cleared_ = true; 968 on_clear_callback.Run(); 969} 970 971void SigninScreenHandler::OnKeyEvent(ui::KeyEvent* key) { 972 if (key->type() == ui::ET_KEY_PRESSED && 973 key->key_code() == ui::VKEY_CAPITAL) { 974 caps_lock_enabled_ = !caps_lock_enabled_; 975 if (page_is_ready()) 976 CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_); 977 } 978} 979 980void SigninScreenHandler::Observe(int type, 981 const content::NotificationSource& source, 982 const content::NotificationDetails& details) { 983 switch (type) { 984 case chrome::NOTIFICATION_AUTH_NEEDED: { 985 has_pending_auth_ui_ = true; 986 break; 987 } 988 case chrome::NOTIFICATION_AUTH_SUPPLIED: 989 has_pending_auth_ui_ = false; 990 if (IsSigninScreenHiddenByError()) { 991 // Hide error screen and reload auth extension. 992 HideOfflineMessage(network_state_informer_->state(), 993 ErrorScreenActor::ERROR_REASON_PROXY_AUTH_SUPPLIED); 994 } else if (ui_state_ == UI_STATE_GAIA_SIGNIN) { 995 // Reload auth extension as proxy credentials are supplied. 996 ReloadGaiaScreen(); 997 } 998 break; 999 case chrome::NOTIFICATION_AUTH_CANCELLED: { 1000 // Don't reload auth extension if proxy auth dialog was cancelled. 1001 has_pending_auth_ui_ = false; 1002 break; 1003 } 1004 default: 1005 NOTREACHED() << "Unexpected notification " << type; 1006 } 1007} 1008 1009void SigninScreenHandler::OnDnsCleared() { 1010 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1011 dns_clear_task_running_ = false; 1012 dns_cleared_ = true; 1013 ShowSigninScreenIfReady(); 1014} 1015 1016// Update keyboard layout to least recently used by the user. 1017void SigninScreenHandler::SetUserInputMethod(const std::string& username) { 1018 UserManager* user_manager = UserManager::Get(); 1019 if (user_manager->IsUserLoggedIn()) { 1020 // We are on sign-in screen inside user session (adding new user to 1021 // the session or on lock screen), don't switch input methods in this case. 1022 // TODO(dpolukhin): adding user and sign-in should be consistent 1023 // crbug.com/292774 1024 return; 1025 } 1026 1027 chromeos::input_method::InputMethodManager* const manager = 1028 chromeos::input_method::InputMethodManager::Get(); 1029 1030 const bool succeed = SetUserInputMethodImpl(username, manager); 1031 1032 // This is also a case when LRU layout is set only for a few local users, 1033 // thus others need to be switched to default locale. 1034 // Otherwise they will end up using another user's locale to log in. 1035 if (!succeed) { 1036 DVLOG(0) << "SetUserInputMethod('" << username 1037 << "'): failed to set user layout. Switching to default."; 1038 1039 manager->SetInputMethodLoginDefault(); 1040 } 1041} 1042 1043void SigninScreenHandler::ShowSigninScreenIfReady() { 1044 LOG(WARNING) << "ShowSigninScreenIfReady() call."; 1045 1046 if (!dns_cleared_ || !cookies_cleared_ || !delegate_) 1047 return; 1048 1049 std::string active_network_path = network_state_informer_->network_path(); 1050 if (gaia_silent_load_ && 1051 (network_state_informer_->state() != NetworkStateInformer::ONLINE || 1052 gaia_silent_load_network_ != active_network_path)) { 1053 // Network has changed. Force Gaia reload. 1054 gaia_silent_load_ = false; 1055 } 1056 1057 // Note that LoadAuthExtension clears |email_|. 1058 if (email_.empty()) 1059 delegate_->LoadSigninWallpaper(); 1060 else 1061 delegate_->LoadWallpaper(email_); 1062 1063 // Set Least Recently Used input method for the user. 1064 if (!email_.empty()) 1065 SetUserInputMethod(email_); 1066 1067 LoadAuthExtension(!gaia_silent_load_, false, false); 1068 UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL); 1069 1070 if (gaia_silent_load_) { 1071 // The variable is assigned to false because silently loaded Gaia page was 1072 // used. 1073 gaia_silent_load_ = false; 1074 HandleLoginWebuiReady(); 1075 } 1076 1077 UpdateState(ErrorScreenActor::ERROR_REASON_UPDATE); 1078} 1079 1080void SigninScreenHandler::LoadAuthExtension( 1081 bool force, bool silent_load, bool offline) { 1082 GaiaContext context; 1083 context.force_reload = force; 1084 context.is_local = offline; 1085 context.password_changed = 1086 !email_.empty() && password_changed_for_.count(email_); 1087 if (delegate_) 1088 context.show_users = delegate_->IsShowUsers(); 1089 context.use_offline = offline; 1090 if (delegate_) 1091 context.has_users = !delegate_->GetUsers().empty(); 1092 context.email = email_; 1093 1094 email_.clear(); 1095 1096 DCHECK(gaia_screen_handler_); 1097 gaia_screen_handler_->LoadGaia(context); 1098} 1099 1100void SigninScreenHandler::UserSettingsChanged() { 1101 DCHECK(gaia_screen_handler_); 1102 GaiaContext context; 1103 if (delegate_) 1104 context.has_users = !delegate_->GetUsers().empty(); 1105 gaia_screen_handler_->UpdateGaia(context); 1106 UpdateAddButtonStatus(); 1107} 1108 1109void SigninScreenHandler::UpdateAddButtonStatus() { 1110 CallJS("cr.ui.login.DisplayManager.updateAddUserButtonStatus", 1111 AllWhitelistedUsersPresent()); 1112} 1113 1114void SigninScreenHandler::HandleUsingSAMLAPI() { 1115 SetSAMLPrincipalsAPIUsed(true); 1116} 1117 1118void SigninScreenHandler::HandleScrapedPasswordCount(int password_count) { 1119 SetSAMLPrincipalsAPIUsed(false); 1120 // Use a histogram that has 11 buckets, one for each of the values in [0, 9] 1121 // and an overflow bucket at the end. 1122 UMA_HISTOGRAM_ENUMERATION( 1123 "ChromeOS.SAML.Scraping.PasswordCount", std::min(password_count, 10), 11); 1124 if (password_count == 0) 1125 HandleScrapedPasswordVerificationFailed(); 1126} 1127 1128void SigninScreenHandler::HandleScrapedPasswordVerificationFailed() { 1129 RecordSAMLScrapingVerificationResultInHistogram(false); 1130} 1131 1132void SigninScreenHandler::HandleCompleteLogin(const std::string& typed_email, 1133 const std::string& password, 1134 bool using_saml) { 1135 if (!delegate_) 1136 return; 1137 1138 if (using_saml && !using_saml_api_) 1139 RecordSAMLScrapingVerificationResultInHistogram(true); 1140 1141 const std::string sanitized_email = gaia::SanitizeEmail(typed_email); 1142 delegate_->SetDisplayEmail(sanitized_email); 1143 delegate_->CompleteLogin(UserContext( 1144 sanitized_email, 1145 password, 1146 std::string(), // auth_code 1147 std::string(), // username_hash 1148 true, // using_oauth 1149 using_saml ? UserContext::AUTH_FLOW_GAIA_WITH_SAML 1150 : UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML)); 1151 1152 if (test_expects_complete_login_) { 1153 VLOG(2) << "Complete test login for " << typed_email 1154 << ", requested=" << test_user_; 1155 1156 test_expects_complete_login_ = false; 1157 test_user_.clear(); 1158 test_pass_.clear(); 1159 } 1160} 1161 1162void SigninScreenHandler::HandleCompleteAuthentication( 1163 const std::string& email, 1164 const std::string& password, 1165 const std::string& auth_code) { 1166 if (!delegate_) 1167 return; 1168 const std::string sanitized_email = gaia::SanitizeEmail(email); 1169 delegate_->SetDisplayEmail(sanitized_email); 1170 delegate_->CompleteLogin(UserContext(sanitized_email, password, auth_code)); 1171} 1172 1173void SigninScreenHandler::HandleAuthenticateUser(const std::string& username, 1174 const std::string& password) { 1175 if (!delegate_) 1176 return; 1177 delegate_->Login(UserContext(gaia::SanitizeEmail(username), 1178 password, 1179 std::string())); // auth_code 1180} 1181 1182void SigninScreenHandler::HandleLaunchDemoUser() { 1183 if (delegate_) 1184 delegate_->LoginAsRetailModeUser(); 1185} 1186 1187void SigninScreenHandler::HandleLaunchIncognito() { 1188 if (delegate_) 1189 delegate_->LoginAsGuest(); 1190} 1191 1192void SigninScreenHandler::HandleShowLocallyManagedUserCreationScreen() { 1193 if (!UserManager::Get()->AreLocallyManagedUsersAllowed()) { 1194 LOG(ERROR) << "Managed users not allowed."; 1195 return; 1196 } 1197 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue()); 1198 LoginDisplayHostImpl::default_host()-> 1199 StartWizard(WizardController::kLocallyManagedUserCreationScreenName, 1200 params.Pass()); 1201} 1202 1203void SigninScreenHandler::HandleLaunchPublicAccount( 1204 const std::string& username) { 1205 if (delegate_) 1206 delegate_->LoginAsPublicAccount(username); 1207} 1208 1209void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) { 1210 if (!delegate_ || delegate_->IsShowUsers()) { 1211 NOTREACHED(); 1212 return; 1213 } 1214 if (!args->GetString(0, &email_)) 1215 email_.clear(); 1216 // Load auth extension. Parameters are: force reload, do not load extension in 1217 // background, use offline version. 1218 LoadAuthExtension(true, false, true); 1219 UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL); 1220} 1221 1222void SigninScreenHandler::HandleShutdownSystem() { 1223 ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown(); 1224} 1225 1226void SigninScreenHandler::HandleLoadWallpaper(const std::string& email) { 1227 if (delegate_) 1228 delegate_->LoadWallpaper(email); 1229} 1230 1231void SigninScreenHandler::HandleRebootSystem() { 1232 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); 1233} 1234 1235void SigninScreenHandler::HandleRemoveUser(const std::string& email) { 1236 if (!delegate_) 1237 return; 1238 delegate_->RemoveUser(email); 1239 UpdateAddButtonStatus(); 1240} 1241 1242void SigninScreenHandler::HandleShowAddUser(const base::ListValue* args) { 1243 TRACE_EVENT_ASYNC_STEP_INTO0("ui", 1244 "ShowLoginWebUI", 1245 LoginDisplayHostImpl::kShowLoginWebUIid, 1246 "ShowAddUser"); 1247 std::string email; 1248 // |args| can be null if it's OOBE. 1249 if (args) 1250 args->GetString(0, &email); 1251 OnShowAddUser(email); 1252} 1253 1254void SigninScreenHandler::HandleToggleEnrollmentScreen() { 1255 if (delegate_) 1256 delegate_->ShowEnterpriseEnrollmentScreen(); 1257} 1258 1259void SigninScreenHandler::HandleToggleKioskEnableScreen() { 1260 policy::BrowserPolicyConnectorChromeOS* connector = 1261 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 1262 if (delegate_ && 1263 !auto_enrollment_progress_subscription_ && 1264 !connector->IsEnterpriseManaged() && 1265 LoginDisplayHostImpl::default_host()) { 1266 AutoEnrollmentController* auto_enrollment_controller = 1267 LoginDisplayHostImpl::default_host()->GetAutoEnrollmentController(); 1268 auto_enrollment_progress_subscription_ = 1269 auto_enrollment_controller->RegisterProgressCallback( 1270 base::Bind(&SigninScreenHandler::ContinueKioskEnableFlow, 1271 weak_factory_.GetWeakPtr())); 1272 ContinueKioskEnableFlow(auto_enrollment_controller->state()); 1273 } 1274} 1275 1276void SigninScreenHandler::HandleToggleResetScreen() { 1277 policy::BrowserPolicyConnectorChromeOS* connector = 1278 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 1279 if (delegate_ && !connector->IsEnterpriseManaged()) 1280 delegate_->ShowResetScreen(); 1281} 1282 1283void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() { 1284 policy::BrowserPolicyConnectorChromeOS* connector = 1285 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 1286 if (delegate_ && !connector->IsEnterpriseManaged()) 1287 delegate_->ShowKioskAutolaunchScreen(); 1288} 1289 1290void SigninScreenHandler::FillUserDictionary(User* user, 1291 bool is_owner, 1292 bool is_signin_to_add, 1293 LoginDisplay::AuthType auth_type, 1294 base::DictionaryValue* user_dict) { 1295 const std::string& email = user->email(); 1296 const bool is_public_account = 1297 user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT; 1298 const bool is_locally_managed_user = 1299 user->GetType() == User::USER_TYPE_LOCALLY_MANAGED; 1300 1301 user_dict->SetString(kKeyUsername, email); 1302 user_dict->SetString(kKeyEmailAddress, user->display_email()); 1303 user_dict->SetString(kKeyDisplayName, user->GetDisplayName()); 1304 user_dict->SetBoolean(kKeyPublicAccount, is_public_account); 1305 user_dict->SetBoolean(kKeyLocallyManagedUser, is_locally_managed_user); 1306 user_dict->SetInteger(kKeyInitialAuthType, auth_type); 1307 user_dict->SetBoolean(kKeySignedIn, user->is_logged_in()); 1308 user_dict->SetBoolean(kKeyIsOwner, is_owner); 1309 1310 // Fill in multi-profiles related fields. 1311 if (is_signin_to_add) { 1312 MultiProfileUserController* multi_profile_user_controller = 1313 UserManager::Get()->GetMultiProfileUserController(); 1314 std::string behavior = multi_profile_user_controller-> 1315 GetCachedValue(user->email()); 1316 user_dict->SetBoolean(kKeyMultiProfilesAllowed, 1317 multi_profile_user_controller->IsUserAllowedInSession(email) == 1318 MultiProfileUserController::ALLOWED); 1319 user_dict->SetString(kKeyMultiProfilesPolicy, behavior); 1320 } else { 1321 user_dict->SetBoolean(kKeyMultiProfilesAllowed, true); 1322 } 1323 1324 if (is_public_account) { 1325 policy::BrowserPolicyConnectorChromeOS* policy_connector = 1326 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 1327 1328 if (policy_connector->IsEnterpriseManaged()) { 1329 user_dict->SetString(kKeyEnterpriseDomain, 1330 policy_connector->GetEnterpriseDomain()); 1331 } 1332 } 1333} 1334 1335void SigninScreenHandler::SendUserList(bool animated) { 1336 if (!delegate_) 1337 return; 1338 TRACE_EVENT_ASYNC_STEP_INTO0("ui", 1339 "ShowLoginWebUI", 1340 LoginDisplayHostImpl::kShowLoginWebUIid, 1341 "SendUserList"); 1342 BootTimesLoader::Get()->RecordCurrentStats("login-send-user-list"); 1343 1344 base::ListValue users_list; 1345 const UserList& users = delegate_->GetUsers(); 1346 1347 // TODO(nkostylev): Move to a separate method in UserManager. 1348 // http://crbug.com/230852 1349 bool is_signin_to_add = LoginDisplayHostImpl::default_host() && 1350 UserManager::Get()->IsUserLoggedIn(); 1351 1352 user_pod_button_callback_map_.clear(); 1353 user_auth_type_map_.clear(); 1354 1355 bool single_user = users.size() == 1; 1356 std::string owner; 1357 chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner); 1358 bool has_owner = owner.size() > 0; 1359 size_t max_non_owner_users = has_owner ? kMaxUsers - 1 : kMaxUsers; 1360 size_t non_owner_count = 0; 1361 policy::BrowserPolicyConnectorChromeOS* connector = 1362 g_browser_process->platform_part()-> 1363 browser_policy_connector_chromeos(); 1364 bool is_enterprise_managed = connector->IsEnterpriseManaged(); 1365 1366 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { 1367 const std::string& email = (*it)->email(); 1368 bool is_owner = (email == owner); 1369 bool is_public_account = 1370 ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT); 1371 1372 if ((is_public_account && !is_signin_to_add) || 1373 is_owner || 1374 (!is_public_account && non_owner_count < max_non_owner_users)) { 1375 LoginDisplay::AuthType initial_auth_type = 1376 ShouldForceOnlineSignIn(*it) ? LoginDisplay::ONLINE_SIGN_IN 1377 : LoginDisplay::OFFLINE_PASSWORD; 1378 user_auth_type_map_[email] = initial_auth_type; 1379 1380 base::DictionaryValue* user_dict = new base::DictionaryValue(); 1381 FillUserDictionary( 1382 *it, is_owner, is_signin_to_add, initial_auth_type, user_dict); 1383 bool signed_in = (*it)->is_logged_in(); 1384 // Single user check here is necessary because owner info might not be 1385 // available when running into login screen on first boot. 1386 // See http://crosbug.com/12723 1387 bool can_remove_user = ((!single_user || is_enterprise_managed) && 1388 !email.empty() && !is_owner && !is_public_account && 1389 !signed_in && !is_signin_to_add); 1390 user_dict->SetBoolean(kKeyCanRemove, can_remove_user); 1391 1392 if (is_owner) { 1393 users_list.Insert(0, user_dict); 1394 } else { 1395 ++non_owner_count; 1396 users_list.Append(user_dict); 1397 } 1398 } 1399 } 1400 while (users_list.GetSize() > kMaxUsers) 1401 users_list.Remove(kMaxUsers, NULL); 1402 1403 CallJS("login.AccountPickerScreen.loadUsers", users_list, animated, 1404 delegate_->IsShowGuest()); 1405} 1406 1407void SigninScreenHandler::HandleAccountPickerReady() { 1408 VLOG(0) << "Login WebUI >> AccountPickerReady"; 1409 1410 if (delegate_ && !ScreenLocker::default_screen_locker() && 1411 !chromeos::IsMachineHWIDCorrect() && 1412 !oobe_ui_) { 1413 delegate_->ShowWrongHWIDScreen(); 1414 return; 1415 } 1416 1417 PrefService* prefs = g_browser_process->local_state(); 1418 if (prefs->GetBoolean(prefs::kFactoryResetRequested)) { 1419 HandleToggleResetScreen(); 1420 return; 1421 } 1422 1423 is_account_picker_showing_first_time_ = true; 1424 MaybePreloadAuthExtension(); 1425 1426 if (ScreenLocker::default_screen_locker()) 1427 ScreenLocker::default_screen_locker()->delegate()->OnLockWebUIReady(); 1428 1429 if (delegate_) 1430 delegate_->OnSigninScreenReady(); 1431} 1432 1433void SigninScreenHandler::HandleWallpaperReady() { 1434 if (ScreenLocker::default_screen_locker()) { 1435 ScreenLocker::default_screen_locker()->delegate()-> 1436 OnLockBackgroundDisplayed(); 1437 } 1438} 1439 1440void SigninScreenHandler::HandleLoginWebuiReady() { 1441 if (gaia_silent_load_) { 1442 // As we could miss and window.onload could already be called, restore 1443 // focus to current pod (see crbug/175243). 1444 RefocusCurrentPod(); 1445 } 1446 DCHECK(gaia_screen_handler_); 1447 gaia_screen_handler_->HandleFrameLoadingCompleted(0); 1448 1449 if (test_expects_complete_login_) 1450 SubmitLoginFormForTest(); 1451} 1452 1453void SigninScreenHandler::HandleSignOutUser() { 1454 if (delegate_) 1455 delegate_->Signout(); 1456} 1457 1458void SigninScreenHandler::HandleNetworkErrorShown() { 1459 content::NotificationService::current()->Notify( 1460 chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN, 1461 content::NotificationService::AllSources(), 1462 content::NotificationService::NoDetails()); 1463} 1464 1465void SigninScreenHandler::HandleCreateAccount() { 1466 if (delegate_) 1467 delegate_->CreateAccount(); 1468} 1469 1470void SigninScreenHandler::HandleOpenProxySettings() { 1471 LoginDisplayHostImpl::default_host()->OpenProxySettings(); 1472} 1473 1474void SigninScreenHandler::HandleLoginVisible(const std::string& source) { 1475 LOG(WARNING) << "Login WebUI >> loginVisible, src: " << source << ", " 1476 << "webui_visible_: " << webui_visible_; 1477 if (!webui_visible_) { 1478 // There might be multiple messages from OOBE UI so send notifications after 1479 // the first one only. 1480 content::NotificationService::current()->Notify( 1481 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 1482 content::NotificationService::AllSources(), 1483 content::NotificationService::NoDetails()); 1484 TRACE_EVENT_ASYNC_END0( 1485 "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid); 1486 } 1487 webui_visible_ = true; 1488 if (preferences_changed_delayed_) 1489 OnPreferencesChanged(); 1490} 1491 1492void SigninScreenHandler::HandleCancelPasswordChangedFlow() { 1493 StartClearingCookies(base::Bind( 1494 &SigninScreenHandler::CancelPasswordChangedFlowInternal, 1495 weak_factory_.GetWeakPtr())); 1496} 1497 1498void SigninScreenHandler::HandleCancelUserAdding() { 1499 if (delegate_) 1500 delegate_->CancelUserAdding(); 1501} 1502 1503void SigninScreenHandler::HandleMigrateUserData( 1504 const std::string& old_password) { 1505 if (delegate_) 1506 delegate_->MigrateUserData(old_password); 1507} 1508 1509void SigninScreenHandler::HandleResyncUserData() { 1510 if (delegate_) 1511 delegate_->ResyncUserData(); 1512} 1513 1514void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source, 1515 bool new_value) { 1516 VLOG(0) << "Login WebUI >> active: " << new_value << ", " 1517 << "source: " << source; 1518 1519 if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() && 1520 KioskAppManager::Get()->IsAutoLaunchRequested()) { 1521 VLOG(0) << "Showing auto-launch warning"; 1522 // On slow devices, the wallpaper animation is not shown initially, so we 1523 // must explicitly load the wallpaper. This is also the case for the 1524 // account-picker and gaia-signin UI states. 1525 delegate_->LoadSigninWallpaper(); 1526 HandleToggleKioskAutolaunchScreen(); 1527 return; 1528 } 1529 1530 if (source == kSourceGaiaSignin) { 1531 ui_state_ = UI_STATE_GAIA_SIGNIN; 1532 } else if (source == kSourceAccountPicker) { 1533 ui_state_ = UI_STATE_ACCOUNT_PICKER; 1534 } else { 1535 NOTREACHED(); 1536 return; 1537 } 1538} 1539 1540void SigninScreenHandler::HandleUnlockOnLoginSuccess() { 1541 DCHECK(UserManager::Get()->IsUserLoggedIn()); 1542 if (ScreenLocker::default_screen_locker()) 1543 ScreenLocker::default_screen_locker()->UnlockOnLoginSuccess(); 1544} 1545 1546void SigninScreenHandler::HandleShowLoadingTimeoutError() { 1547 UpdateState(ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT); 1548} 1549 1550void SigninScreenHandler::HandleUpdateOfflineLogin(bool offline_login_active) { 1551 offline_login_active_ = offline_login_active; 1552} 1553 1554void SigninScreenHandler::HandleFocusPod(const std::string& user_id) { 1555 SetUserInputMethod(user_id); 1556 WallpaperManager::Get()->SetUserWallpaperDelayed(user_id); 1557} 1558 1559void SigninScreenHandler::HandleCustomButtonClicked( 1560 const std::string& username) { 1561 if (user_pod_button_callback_map_.find(username) 1562 == user_pod_button_callback_map_.end()) { 1563 LOG(WARNING) << "User pod custom button clicked but no callback found"; 1564 return; 1565 } 1566 user_pod_button_callback_map_[username].Run(); 1567} 1568 1569void SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail( 1570 double attempt_token) { 1571 email_retriever_.reset(new AuthenticatedUserEmailRetriever( 1572 base::Bind(&SigninScreenHandler::CallJS<double, std::string>, 1573 base::Unretained(this), 1574 "login.GaiaSigninScreen.setAuthenticatedUserEmail", 1575 attempt_token), 1576 Profile::FromWebUI(web_ui())->GetRequestContext())); 1577} 1578 1579void SigninScreenHandler::HandleLaunchKioskApp(const std::string& app_id, 1580 bool diagnostic_mode) { 1581 delegate_->LoginAsKioskApp(app_id, diagnostic_mode); 1582} 1583 1584void SigninScreenHandler::StartClearingDnsCache() { 1585 if (dns_clear_task_running_ || !g_browser_process->io_thread()) 1586 return; 1587 1588 dns_cleared_ = false; 1589 BrowserThread::PostTaskAndReply( 1590 BrowserThread::IO, FROM_HERE, 1591 base::Bind(&ClearDnsCache, g_browser_process->io_thread()), 1592 base::Bind(&SigninScreenHandler::OnDnsCleared, 1593 weak_factory_.GetWeakPtr())); 1594 dns_clear_task_running_ = true; 1595} 1596 1597void SigninScreenHandler::StartClearingCookies( 1598 const base::Closure& on_clear_callback) { 1599 cookies_cleared_ = false; 1600 ProfileHelper* profile_helper = 1601 g_browser_process->platform_part()->profile_helper(); 1602 LOG_ASSERT( 1603 Profile::FromWebUI(web_ui()) == profile_helper->GetSigninProfile()); 1604 profile_helper->ClearSigninProfile(base::Bind( 1605 &SigninScreenHandler::OnCookiesCleared, 1606 weak_factory_.GetWeakPtr(), on_clear_callback)); 1607} 1608 1609void SigninScreenHandler::MaybePreloadAuthExtension() { 1610 LOG(WARNING) << "MaybePreloadAuthExtension() call."; 1611 1612 // Fetching of the extension is not started before account picker page is 1613 // loaded because it can affect the loading speed. Also if cookies clearing 1614 // was initiated or |dns_clear_task_running_| then auth extension showing has 1615 // already been initiated and preloading is senseless. 1616 // Do not load the extension for the screen locker, see crosbug.com/25018. 1617 if (is_account_picker_showing_first_time_ && 1618 !gaia_silent_load_ && 1619 !ScreenLocker::default_screen_locker() && 1620 !cookies_cleared_ && 1621 !dns_clear_task_running_ && 1622 network_state_informer_->state() == NetworkStateInformer::ONLINE) { 1623 gaia_silent_load_ = true; 1624 gaia_silent_load_network_ = network_state_informer_->network_path(); 1625 LoadAuthExtension(true, true, false); 1626 } 1627} 1628 1629bool SigninScreenHandler::AllWhitelistedUsersPresent() { 1630 CrosSettings* cros_settings = CrosSettings::Get(); 1631 bool allow_new_user = false; 1632 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); 1633 if (allow_new_user) 1634 return false; 1635 UserManager* user_manager = UserManager::Get(); 1636 const UserList& users = user_manager->GetUsers(); 1637 if (!delegate_ || users.size() > kMaxUsers) { 1638 return false; 1639 } 1640 const base::ListValue* whitelist = NULL; 1641 if (!cros_settings->GetList(kAccountsPrefUsers, &whitelist) || !whitelist) 1642 return false; 1643 for (size_t i = 0; i < whitelist->GetSize(); ++i) { 1644 std::string whitelisted_user; 1645 // NB: Wildcards in the whitelist are also detected as not present here. 1646 if (!whitelist->GetString(i, &whitelisted_user) || 1647 !user_manager->IsKnownUser(whitelisted_user)) { 1648 return false; 1649 } 1650 } 1651 return true; 1652} 1653 1654void SigninScreenHandler::CancelPasswordChangedFlowInternal() { 1655 if (delegate_) { 1656 ShowImpl(); 1657 delegate_->CancelPasswordChangedFlow(); 1658 } 1659} 1660 1661OobeUI::Screen SigninScreenHandler::GetCurrentScreen() const { 1662 OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN; 1663 OobeUI* oobe_ui = static_cast<OobeUI*>(web_ui()->GetController()); 1664 if (oobe_ui) 1665 screen = oobe_ui->current_screen(); 1666 return screen; 1667} 1668 1669bool SigninScreenHandler::IsGaiaVisible() const { 1670 return IsSigninScreen(GetCurrentScreen()) && 1671 ui_state_ == UI_STATE_GAIA_SIGNIN; 1672} 1673 1674bool SigninScreenHandler::IsGaiaHiddenByError() const { 1675 return IsSigninScreenHiddenByError() && 1676 ui_state_ == UI_STATE_GAIA_SIGNIN; 1677} 1678 1679bool SigninScreenHandler::IsSigninScreenHiddenByError() const { 1680 return (GetCurrentScreen() == OobeUI::SCREEN_ERROR_MESSAGE) && 1681 (IsSigninScreen(error_screen_actor_->parent_screen())); 1682} 1683 1684bool SigninScreenHandler::IsGuestSigninAllowed() const { 1685 CrosSettings* cros_settings = CrosSettings::Get(); 1686 if (!cros_settings) 1687 return false; 1688 bool allow_guest; 1689 cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest); 1690 return allow_guest; 1691} 1692 1693bool SigninScreenHandler::IsOfflineLoginAllowed() const { 1694 CrosSettings* cros_settings = CrosSettings::Get(); 1695 if (!cros_settings) 1696 return false; 1697 1698 // Offline login is allowed only when user pods are hidden. 1699 bool show_pods; 1700 cros_settings->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_pods); 1701 return !show_pods; 1702} 1703 1704void SigninScreenHandler::SubmitLoginFormForTest() { 1705 VLOG(2) << "Submit login form for test, user=" << test_user_; 1706 1707 std::string code; 1708 code += "document.getElementById('Email').value = '" + test_user_ + "';"; 1709 code += "document.getElementById('Passwd').value = '" + test_pass_ + "';"; 1710 code += "document.getElementById('signIn').click();"; 1711 1712 content::RenderFrameHost* frame = 1713 LoginDisplayHostImpl::GetGaiaAuthIframe(web_ui()->GetWebContents()); 1714 frame->ExecuteJavaScript(base::ASCIIToUTF16(code)); 1715 1716 // Test properties are cleared in HandleCompleteLogin because the form 1717 // submission might fail and login will not be attempted after reloading 1718 // if they are cleared here. 1719} 1720 1721void SigninScreenHandler::ContinueKioskEnableFlow( 1722 policy::AutoEnrollmentState state) { 1723 // Do not proceed with kiosk enable when auto enroll will be enforced. 1724 // TODO(xiyuan): Add an error UI feedkback so user knows what happens. 1725 switch (state) { 1726 case policy::AUTO_ENROLLMENT_STATE_IDLE: 1727 case policy::AUTO_ENROLLMENT_STATE_PENDING: 1728 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR: 1729 // Wait for the next callback. 1730 return; 1731 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT: 1732 // Auto-enrollment is on. 1733 LOG(WARNING) << "Kiosk enable flow aborted because auto enrollment is " 1734 "going to be enforced."; 1735 if (!kiosk_enable_flow_aborted_callback_for_test_.is_null()) 1736 kiosk_enable_flow_aborted_callback_for_test_.Run(); 1737 break; 1738 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR: 1739 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT: 1740 // Auto-enrollment not applicable. 1741 if (delegate_) 1742 delegate_->ShowKioskEnableScreen(); 1743 break; 1744 } 1745 auto_enrollment_progress_subscription_.reset(); 1746} 1747 1748void SigninScreenHandler::OnShowAddUser(const std::string& email) { 1749 email_ = email; 1750 is_account_picker_showing_first_time_ = false; 1751 1752 if (gaia_silent_load_ && email_.empty()) { 1753 dns_cleared_ = true; 1754 cookies_cleared_ = true; 1755 ShowSigninScreenIfReady(); 1756 } else { 1757 StartClearingDnsCache(); 1758 StartClearingCookies(base::Bind( 1759 &SigninScreenHandler::ShowSigninScreenIfReady, 1760 weak_factory_.GetWeakPtr())); 1761 } 1762} 1763 1764void SigninScreenHandler::SetSAMLPrincipalsAPIUsed(bool api_used) { 1765 using_saml_api_ = api_used; 1766 UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.APIUsed", api_used); 1767} 1768 1769GaiaScreenHandler::FrameState SigninScreenHandler::FrameState() const { 1770 DCHECK(gaia_screen_handler_); 1771 return gaia_screen_handler_->frame_state(); 1772} 1773 1774net::Error SigninScreenHandler::FrameError() const { 1775 DCHECK(gaia_screen_handler_); 1776 return gaia_screen_handler_->frame_error(); 1777} 1778 1779} // namespace chromeos 1780