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