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