Home | History | Annotate | Download | only in login
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
      6 
      7 #include <algorithm>
      8 #include <vector>
      9 
     10 #include "base/bind.h"
     11 #include "base/bind_helpers.h"
     12 #include "base/debug/trace_event.h"
     13 #include "base/location.h"
     14 #include "base/logging.h"
     15 #include "base/metrics/histogram.h"
     16 #include "base/prefs/pref_registry_simple.h"
     17 #include "base/prefs/pref_service.h"
     18 #include "base/prefs/scoped_user_pref_update.h"
     19 #include "base/strings/string16.h"
     20 #include "base/strings/string_util.h"
     21 #include "base/strings/stringprintf.h"
     22 #include "base/strings/utf_string_conversions.h"
     23 #include "base/sys_info.h"
     24 #include "chrome/browser/browser_process.h"
     25 #include "chrome/browser/browser_process_platform_part_chromeos.h"
     26 #include "chrome/browser/browser_shutdown.h"
     27 #include "chrome/browser/chrome_notification_types.h"
     28 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
     29 #include "chrome/browser/chromeos/boot_times_loader.h"
     30 #include "chrome/browser/chromeos/input_method/input_method_util.h"
     31 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
     32 #include "chrome/browser/chromeos/login/hwid_checker.h"
     33 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
     34 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
     35 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
     36 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
     37 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
     38 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
     39 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
     40 #include "chrome/browser/chromeos/login/wizard_controller.h"
     41 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
     42 #include "chrome/browser/chromeos/policy/consumer_management_service.h"
     43 #include "chrome/browser/chromeos/policy/device_local_account.h"
     44 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     45 #include "chrome/browser/chromeos/settings/cros_settings.h"
     46 #include "chrome/browser/io_thread.h"
     47 #include "chrome/browser/profiles/profile.h"
     48 #include "chrome/browser/signin/easy_unlock_service.h"
     49 #include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h"
     50 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
     51 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
     52 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
     53 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
     54 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
     55 #include "chrome/common/pref_names.h"
     56 #include "chrome/common/url_constants.h"
     57 #include "chrome/grit/chromium_strings.h"
     58 #include "chrome/grit/generated_resources.h"
     59 #include "chromeos/dbus/dbus_thread_manager.h"
     60 #include "chromeos/dbus/power_manager_client.h"
     61 #include "chromeos/ime/ime_keyboard.h"
     62 #include "chromeos/ime/input_method_descriptor.h"
     63 #include "chromeos/ime/input_method_manager.h"
     64 #include "chromeos/login/auth/key.h"
     65 #include "chromeos/login/auth/user_context.h"
     66 #include "chromeos/network/network_state.h"
     67 #include "chromeos/network/network_state_handler.h"
     68 #include "chromeos/network/portal_detector/network_portal_detector.h"
     69 #include "components/user_manager/user.h"
     70 #include "components/user_manager/user_manager.h"
     71 #include "components/user_manager/user_type.h"
     72 #include "content/public/browser/render_frame_host.h"
     73 #include "content/public/browser/web_contents.h"
     74 #include "google_apis/gaia/gaia_auth_util.h"
     75 #include "net/url_request/url_request_context_getter.h"
     76 #include "third_party/cros_system_api/dbus/service_constants.h"
     77 #include "ui/base/webui/web_ui_util.h"
     78 
     79 #if defined(USE_AURA)
     80 #include "ash/shell.h"
     81 #include "ash/wm/lock_state_controller.h"
     82 #endif
     83 
     84 namespace {
     85 
     86 // Max number of users to show.
     87 const size_t kMaxUsers = 18;
     88 
     89 // Timeout to delay first notification about offline state for a
     90 // current network.
     91 const int kOfflineTimeoutSec = 5;
     92 
     93 // Timeout used to prevent infinite connecting to a flaky network.
     94 const int kConnectingTimeoutSec = 60;
     95 
     96 // Type of the login screen UI that is currently presented to user.
     97 const char kSourceGaiaSignin[] = "gaia-signin";
     98 const char kSourceAccountPicker[] = "account-picker";
     99 
    100 static bool Contains(const std::vector<std::string>& container,
    101                      const std::string& value) {
    102   return std::find(container.begin(), container.end(), value) !=
    103          container.end();
    104 }
    105 
    106 class CallOnReturn {
    107  public:
    108   explicit CallOnReturn(const base::Closure& callback)
    109       : callback_(callback), call_scheduled_(false) {}
    110 
    111   ~CallOnReturn() {
    112     if (call_scheduled_ && !callback_.is_null())
    113       callback_.Run();
    114   }
    115 
    116   void ScheduleCall() { call_scheduled_ = true; }
    117 
    118  private:
    119   base::Closure callback_;
    120   bool call_scheduled_;
    121 
    122   DISALLOW_COPY_AND_ASSIGN(CallOnReturn);
    123 };
    124 
    125 }  // namespace
    126 
    127 namespace chromeos {
    128 
    129 namespace {
    130 
    131 bool IsOnline(NetworkStateInformer::State state,
    132               ErrorScreenActor::ErrorReason reason) {
    133   return state == NetworkStateInformer::ONLINE &&
    134       reason != ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED &&
    135       reason != ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT;
    136 }
    137 
    138 bool IsBehindCaptivePortal(NetworkStateInformer::State state,
    139                            ErrorScreenActor::ErrorReason reason) {
    140   return state == NetworkStateInformer::CAPTIVE_PORTAL ||
    141       reason == ErrorScreenActor::ERROR_REASON_PORTAL_DETECTED;
    142 }
    143 
    144 bool IsProxyError(NetworkStateInformer::State state,
    145                   ErrorScreenActor::ErrorReason reason,
    146                   net::Error frame_error) {
    147   return state == NetworkStateInformer::PROXY_AUTH_REQUIRED ||
    148       reason == ErrorScreenActor::ERROR_REASON_PROXY_AUTH_CANCELLED ||
    149       reason == ErrorScreenActor::ERROR_REASON_PROXY_CONNECTION_FAILED ||
    150       (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
    151        (frame_error == net::ERR_PROXY_CONNECTION_FAILED ||
    152         frame_error == net::ERR_TUNNEL_CONNECTION_FAILED));
    153 }
    154 
    155 bool IsSigninScreen(const OobeUI::Screen screen) {
    156   return screen == OobeUI::SCREEN_GAIA_SIGNIN ||
    157       screen == OobeUI::SCREEN_ACCOUNT_PICKER;
    158 }
    159 
    160 bool IsSigninScreenError(ErrorScreen::ErrorState error_state) {
    161   return error_state == ErrorScreen::ERROR_STATE_PORTAL ||
    162       error_state == ErrorScreen::ERROR_STATE_OFFLINE ||
    163       error_state == ErrorScreen::ERROR_STATE_PROXY ||
    164       error_state == ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT;
    165 }
    166 
    167 // Returns network name by service path.
    168 std::string GetNetworkName(const std::string& service_path) {
    169   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
    170       GetNetworkState(service_path);
    171   if (!network)
    172     return std::string();
    173   return network->name();
    174 }
    175 
    176 static bool SetUserInputMethodImpl(
    177     const std::string& username,
    178     const std::string& user_input_method,
    179     input_method::InputMethodManager::State* ime_state) {
    180   if (!chromeos::input_method::InputMethodManager::Get()->IsLoginKeyboard(
    181           user_input_method)) {
    182     LOG(WARNING) << "SetUserInputMethod('" << username
    183                  << "'): stored user LRU input method '" << user_input_method
    184                  << "' is no longer Full Latin Keyboard Language"
    185                  << " (entry dropped). Use hardware default instead.";
    186 
    187     PrefService* const local_state = g_browser_process->local_state();
    188     DictionaryPrefUpdate updater(local_state, prefs::kUsersLRUInputMethod);
    189 
    190     base::DictionaryValue* const users_lru_input_methods = updater.Get();
    191     if (users_lru_input_methods != NULL) {
    192       users_lru_input_methods->SetStringWithoutPathExpansion(username, "");
    193     }
    194     return false;
    195   }
    196 
    197   if (!Contains(ime_state->GetActiveInputMethodIds(), user_input_method)) {
    198     if (!ime_state->EnableInputMethod(user_input_method)) {
    199       DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username
    200                   << "'): user input method '" << user_input_method
    201                   << "' is not enabled and enabling failed (ignored!).";
    202     }
    203   }
    204   ime_state->ChangeInputMethod(user_input_method, false /* show_message */);
    205 
    206   return true;
    207 }
    208 
    209 }  // namespace
    210 
    211 // LoginScreenContext implementation ------------------------------------------
    212 
    213 LoginScreenContext::LoginScreenContext() {
    214   Init();
    215 }
    216 
    217 LoginScreenContext::LoginScreenContext(const base::ListValue* args) {
    218   Init();
    219 
    220   if (!args || args->GetSize() == 0)
    221     return;
    222   std::string email;
    223   if (args->GetString(0, &email))
    224     email_ = email;
    225 }
    226 
    227 void LoginScreenContext::Init() {
    228   oobe_ui_ = false;
    229 }
    230 
    231 // SigninScreenHandler implementation ------------------------------------------
    232 
    233 SigninScreenHandler::SigninScreenHandler(
    234     const scoped_refptr<NetworkStateInformer>& network_state_informer,
    235     ErrorScreenActor* error_screen_actor,
    236     CoreOobeActor* core_oobe_actor,
    237     GaiaScreenHandler* gaia_screen_handler)
    238     : ui_state_(UI_STATE_UNKNOWN),
    239       delegate_(NULL),
    240       native_window_delegate_(NULL),
    241       show_on_init_(false),
    242       oobe_ui_(false),
    243       is_account_picker_showing_first_time_(false),
    244       network_state_informer_(network_state_informer),
    245       webui_visible_(false),
    246       preferences_changed_delayed_(false),
    247       error_screen_actor_(error_screen_actor),
    248       core_oobe_actor_(core_oobe_actor),
    249       is_first_update_state_call_(true),
    250       offline_login_active_(false),
    251       last_network_state_(NetworkStateInformer::UNKNOWN),
    252       has_pending_auth_ui_(false),
    253       caps_lock_enabled_(chromeos::input_method::InputMethodManager::Get()
    254                              ->GetImeKeyboard()
    255                              ->CapsLockIsEnabled()),
    256       gaia_screen_handler_(gaia_screen_handler),
    257       oobe_ui_observer_added_(false),
    258       weak_factory_(this) {
    259   DCHECK(network_state_informer_.get());
    260   DCHECK(error_screen_actor_);
    261   DCHECK(core_oobe_actor_);
    262   DCHECK(gaia_screen_handler_);
    263   gaia_screen_handler_->SetSigninScreenHandler(this);
    264   network_state_informer_->AddObserver(this);
    265 
    266   registrar_.Add(this,
    267                  chrome::NOTIFICATION_AUTH_NEEDED,
    268                  content::NotificationService::AllSources());
    269   registrar_.Add(this,
    270                  chrome::NOTIFICATION_AUTH_SUPPLIED,
    271                  content::NotificationService::AllSources());
    272   registrar_.Add(this,
    273                  chrome::NOTIFICATION_AUTH_CANCELLED,
    274                  content::NotificationService::AllSources());
    275 
    276   chromeos::input_method::ImeKeyboard* keyboard =
    277       chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
    278   if (keyboard)
    279     keyboard->AddObserver(this);
    280 
    281 #if !defined(USE_ATHENA)
    282   max_mode_delegate_.reset(new TouchViewControllerDelegate());
    283   max_mode_delegate_->AddObserver(this);
    284 #endif
    285 
    286   policy::ConsumerManagementService* consumer_management =
    287       g_browser_process->platform_part()->browser_policy_connector_chromeos()->
    288           GetConsumerManagementService();
    289   is_enrolling_consumer_management_ =
    290       consumer_management &&
    291       consumer_management->GetEnrollmentStage() ==
    292           policy::ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED;
    293 }
    294 
    295 SigninScreenHandler::~SigninScreenHandler() {
    296   OobeUI* oobe_ui = GetOobeUI();
    297   if (oobe_ui && oobe_ui_observer_added_)
    298     oobe_ui->RemoveObserver(this);
    299   chromeos::input_method::ImeKeyboard* keyboard =
    300       chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
    301   if (keyboard)
    302     keyboard->RemoveObserver(this);
    303   weak_factory_.InvalidateWeakPtrs();
    304   if (delegate_)
    305     delegate_->SetWebUIHandler(NULL);
    306   network_state_informer_->RemoveObserver(this);
    307   if (max_mode_delegate_) {
    308     max_mode_delegate_->RemoveObserver(this);
    309     max_mode_delegate_.reset(NULL);
    310   }
    311   ScreenlockBridge::Get()->SetLockHandler(NULL);
    312   ScreenlockBridge::Get()->SetFocusedUser("");
    313 }
    314 
    315 void SigninScreenHandler::DeclareLocalizedValues(
    316     LocalizedValuesBuilder* builder) {
    317   builder->Add("passwordHint", IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT);
    318   builder->Add("signingIn", IDS_LOGIN_POD_SIGNING_IN);
    319   builder->Add("podMenuButtonAccessibleName",
    320                IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME);
    321   builder->Add("podMenuRemoveItemAccessibleName",
    322                IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME);
    323   builder->Add("passwordFieldAccessibleName",
    324                IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME);
    325   builder->Add("signedIn", IDS_SCREEN_LOCK_ACTIVE_USER);
    326   builder->Add("signinButton", IDS_LOGIN_BUTTON);
    327   builder->Add("launchAppButton", IDS_LAUNCH_APP_BUTTON);
    328   builder->Add("shutDown", IDS_SHUTDOWN_BUTTON);
    329   builder->Add("addUser", IDS_ADD_USER_BUTTON);
    330   builder->Add("browseAsGuest", IDS_GO_INCOGNITO_BUTTON);
    331   builder->Add("cancel", IDS_CANCEL);
    332   builder->Add("signOutUser", IDS_SCREEN_LOCK_SIGN_OUT);
    333   builder->Add("offlineLogin", IDS_OFFLINE_LOGIN_HTML);
    334   builder->Add("ownerUserPattern", IDS_LOGIN_POD_OWNER_USER);
    335   builder->Add("removeUser", IDS_LOGIN_POD_REMOVE_USER);
    336   builder->Add("errorTpmFailureTitle", IDS_LOGIN_ERROR_TPM_FAILURE_TITLE);
    337   builder->Add("errorTpmFailureReboot", IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT);
    338   builder->Add("errorTpmFailureRebootButton",
    339                IDS_LOGIN_ERROR_TPM_FAILURE_REBOOT_BUTTON);
    340 
    341   policy::BrowserPolicyConnectorChromeOS* connector =
    342       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    343   builder->Add("disabledAddUserTooltip",
    344                connector->IsEnterpriseManaged()
    345                    ? IDS_DISABLED_ADD_USER_TOOLTIP_ENTERPRISE
    346                    : IDS_DISABLED_ADD_USER_TOOLTIP);
    347 
    348   builder->Add("supervisedUserExpiredTokenWarning",
    349                IDS_SUPERVISED_USER_EXPIRED_TOKEN_WARNING);
    350   builder->Add("signinBannerText", IDS_LOGIN_USER_ADDING_BANNER);
    351 
    352   // Multi-profiles related strings.
    353   builder->Add("multiProfilesRestrictedPolicyTitle",
    354                IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE);
    355   builder->Add("multiProfilesNotAllowedPolicyMsg",
    356                IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG);
    357   builder->Add("multiProfilesPrimaryOnlyPolicyMsg",
    358                IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG);
    359   builder->Add("multiProfilesOwnerPrimaryOnlyMsg",
    360                IDS_MULTI_PROFILES_OWNER_PRIMARY_ONLY_MSG);
    361 
    362   // Strings used by password changed dialog.
    363   builder->Add("passwordChangedTitle", IDS_LOGIN_PASSWORD_CHANGED_TITLE);
    364   builder->Add("passwordChangedDesc", IDS_LOGIN_PASSWORD_CHANGED_DESC);
    365   builder->AddF("passwordChangedMoreInfo",
    366                 IDS_LOGIN_PASSWORD_CHANGED_MORE_INFO,
    367                 IDS_SHORT_PRODUCT_OS_NAME);
    368 
    369   builder->Add("oldPasswordHint", IDS_LOGIN_PASSWORD_CHANGED_OLD_PASSWORD_HINT);
    370   builder->Add("oldPasswordIncorrect",
    371                IDS_LOGIN_PASSWORD_CHANGED_INCORRECT_OLD_PASSWORD);
    372   builder->Add("passwordChangedCantRemember",
    373                IDS_LOGIN_PASSWORD_CHANGED_CANT_REMEMBER);
    374   builder->Add("passwordChangedBackButton",
    375                IDS_LOGIN_PASSWORD_CHANGED_BACK_BUTTON);
    376   builder->Add("passwordChangedsOkButton", IDS_OK);
    377   builder->Add("passwordChangedProceedAnyway",
    378                IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY);
    379   builder->Add("proceedAnywayButton",
    380                IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY_BUTTON);
    381   builder->Add("publicAccountInfoFormat", IDS_LOGIN_PUBLIC_ACCOUNT_INFO_FORMAT);
    382   builder->Add("publicAccountReminder",
    383                IDS_LOGIN_PUBLIC_ACCOUNT_SIGNOUT_REMINDER);
    384   builder->Add("publicSessionLanguageAndInput",
    385                IDS_LOGIN_PUBLIC_SESSION_LANGUAGE_AND_INPUT);
    386   builder->Add("publicAccountEnter", IDS_LOGIN_PUBLIC_ACCOUNT_ENTER);
    387   builder->Add("publicAccountEnterAccessibleName",
    388                IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME);
    389   builder->Add("publicSessionSelectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
    390   builder->Add("publicSessionSelectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
    391   builder->Add("removeUserWarningText",
    392                base::string16());
    393   builder->AddF("removeSupervisedUserWarningText",
    394                IDS_LOGIN_POD_SUPERVISED_USER_REMOVE_WARNING,
    395                base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL));
    396   builder->Add("removeUserWarningButtonTitle",
    397                IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON);
    398 
    399   builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE);
    400 
    401   builder->Add("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE);
    402   builder->Add("confirmPasswordLabel", IDS_LOGIN_CONFIRM_PASSWORD_LABEL);
    403   builder->Add("confirmPasswordConfirmButton",
    404                IDS_LOGIN_CONFIRM_PASSWORD_CONFIRM_BUTTON);
    405   builder->Add("confirmPasswordText", IDS_LOGIN_CONFIRM_PASSWORD_TEXT);
    406   builder->Add("confirmPasswordErrorText",
    407                IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT);
    408 
    409   builder->Add("fatalEnrollmentError",
    410                IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR);
    411   builder->Add("insecureURLEnrollmentError",
    412                IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR);
    413 
    414   if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled())
    415     builder->Add("demoLoginMessage", IDS_KIOSK_MODE_LOGIN_MESSAGE);
    416 }
    417 
    418 void SigninScreenHandler::Show(const LoginScreenContext& context) {
    419   CHECK(delegate_);
    420 
    421   // Just initialize internal fields from context and call ShowImpl().
    422   oobe_ui_ = context.oobe_ui();
    423 
    424   std::string email;
    425   if (is_enrolling_consumer_management_) {
    426     // We don't check if the value of the owner e-mail is trusted because it is
    427     // only used to pre-fill the e-mail field in Gaia sign-in page and a cached
    428     // value is sufficient.
    429     CrosSettings::Get()->GetString(kDeviceOwner, &email);
    430   } else {
    431     email = context.email();
    432   }
    433   gaia_screen_handler_->PopulateEmail(email);
    434   ShowImpl();
    435 }
    436 
    437 void SigninScreenHandler::ShowRetailModeLoginSpinner() {
    438   CallJS("showLoginSpinner");
    439 }
    440 
    441 void SigninScreenHandler::SetDelegate(SigninScreenHandlerDelegate* delegate) {
    442   delegate_ = delegate;
    443   if (delegate_)
    444     delegate_->SetWebUIHandler(this);
    445   else
    446     auto_enrollment_progress_subscription_.reset();
    447 }
    448 
    449 void SigninScreenHandler::SetNativeWindowDelegate(
    450     NativeWindowDelegate* native_window_delegate) {
    451   native_window_delegate_ = native_window_delegate;
    452 }
    453 
    454 void SigninScreenHandler::OnNetworkReady() {
    455   VLOG(1) << "OnNetworkReady() call.";
    456   DCHECK(gaia_screen_handler_);
    457   gaia_screen_handler_->MaybePreloadAuthExtension();
    458 }
    459 
    460 void SigninScreenHandler::UpdateState(ErrorScreenActor::ErrorReason reason) {
    461   UpdateStateInternal(reason, false);
    462 }
    463 
    464 void SigninScreenHandler::SetFocusPODCallbackForTesting(
    465     base::Closure callback) {
    466   test_focus_pod_callback_ = callback;
    467 }
    468 
    469 // SigninScreenHandler, private: -----------------------------------------------
    470 
    471 void SigninScreenHandler::ShowImpl() {
    472   if (!page_is_ready()) {
    473     show_on_init_ = true;
    474     return;
    475   }
    476 
    477   if (!ime_state_.get())
    478     ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState();
    479 
    480   if (!oobe_ui_observer_added_) {
    481     oobe_ui_observer_added_ = true;
    482     GetOobeUI()->AddObserver(this);
    483   }
    484 
    485   if (oobe_ui_ || is_enrolling_consumer_management_) {
    486     // Shows new user sign-in for OOBE.
    487     OnShowAddUser();
    488   } else {
    489     // Populates account picker. Animation is turned off for now until we
    490     // figure out how to make it fast enough.
    491     delegate_->HandleGetUsers();
    492 
    493     // Reset Caps Lock state when login screen is shown.
    494     input_method::InputMethodManager::Get()
    495         ->GetImeKeyboard()
    496         ->SetCapsLockEnabled(false);
    497 
    498     base::DictionaryValue params;
    499     params.SetBoolean("disableAddUser", AllWhitelistedUsersPresent());
    500     UpdateUIState(UI_STATE_ACCOUNT_PICKER, &params);
    501   }
    502 }
    503 
    504 void SigninScreenHandler::UpdateUIState(UIState ui_state,
    505                                         base::DictionaryValue* params) {
    506   switch (ui_state) {
    507     case UI_STATE_GAIA_SIGNIN:
    508       ui_state_ = UI_STATE_GAIA_SIGNIN;
    509       ShowScreen(OobeUI::kScreenGaiaSignin, params);
    510       break;
    511     case UI_STATE_ACCOUNT_PICKER:
    512       ui_state_ = UI_STATE_ACCOUNT_PICKER;
    513       ShowScreen(OobeUI::kScreenAccountPicker, params);
    514       break;
    515     default:
    516       NOTREACHED();
    517       break;
    518   }
    519 }
    520 
    521 // TODO(ygorshenin@): split this method into small parts.
    522 // TODO(ygorshenin@): move this logic to GaiaScreenHandler.
    523 void SigninScreenHandler::UpdateStateInternal(
    524     ErrorScreenActor::ErrorReason reason,
    525     bool force_update) {
    526   // Do nothing once user has signed in or sign in is in progress.
    527   // TODO(ygorshenin): We will end up here when processing network state
    528   // notification but no ShowSigninScreen() was called so delegate_ will be
    529   // NULL. Network state processing logic does not belong here.
    530   if (delegate_ &&
    531       (delegate_->IsUserSigninCompleted() || delegate_->IsSigninInProgress())) {
    532     return;
    533   }
    534 
    535   NetworkStateInformer::State state = network_state_informer_->state();
    536   const std::string network_path = network_state_informer_->network_path();
    537   const std::string network_name = GetNetworkName(network_path);
    538 
    539   // Skip "update" notification about OFFLINE state from
    540   // NetworkStateInformer if previous notification already was
    541   // delayed.
    542   if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) &&
    543       !force_update && !update_state_closure_.IsCancelled()) {
    544     return;
    545   }
    546 
    547   update_state_closure_.Cancel();
    548 
    549   if ((state == NetworkStateInformer::OFFLINE && !force_update) ||
    550       has_pending_auth_ui_) {
    551     update_state_closure_.Reset(
    552         base::Bind(&SigninScreenHandler::UpdateStateInternal,
    553                    weak_factory_.GetWeakPtr(),
    554                    reason,
    555                    true));
    556     base::MessageLoop::current()->PostDelayedTask(
    557         FROM_HERE,
    558         update_state_closure_.callback(),
    559         base::TimeDelta::FromSeconds(kOfflineTimeoutSec));
    560     return;
    561   }
    562 
    563   // Don't show or hide error screen if we're in connecting state.
    564   if (state == NetworkStateInformer::CONNECTING && !force_update) {
    565     if (connecting_closure_.IsCancelled()) {
    566       // First notification about CONNECTING state.
    567       connecting_closure_.Reset(
    568           base::Bind(&SigninScreenHandler::UpdateStateInternal,
    569                      weak_factory_.GetWeakPtr(),
    570                      reason,
    571                      true));
    572       base::MessageLoop::current()->PostDelayedTask(
    573           FROM_HERE,
    574           connecting_closure_.callback(),
    575           base::TimeDelta::FromSeconds(kConnectingTimeoutSec));
    576     }
    577     return;
    578   }
    579   connecting_closure_.Cancel();
    580 
    581   const bool is_online = IsOnline(state, reason);
    582   const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
    583   const bool is_gaia_loading_timeout =
    584       (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
    585   const bool is_gaia_error =
    586       FrameError() != net::OK && FrameError() != net::ERR_NETWORK_CHANGED;
    587   const bool is_gaia_signin = IsGaiaVisible() || IsGaiaHiddenByError();
    588   const bool error_screen_should_overlay =
    589       !offline_login_active_ && IsGaiaVisible();
    590   const bool from_not_online_to_online_transition =
    591       is_online && last_network_state_ != NetworkStateInformer::ONLINE;
    592   last_network_state_ = state;
    593 
    594   CallOnReturn reload_gaia(base::Bind(
    595       &SigninScreenHandler::ReloadGaia, weak_factory_.GetWeakPtr(), true));
    596 
    597   if (is_online || !is_behind_captive_portal)
    598     error_screen_actor_->HideCaptivePortal();
    599 
    600   // Hide offline message (if needed) and return if current screen is
    601   // not a Gaia frame.
    602   if (!is_gaia_signin) {
    603     if (!IsSigninScreenHiddenByError())
    604       HideOfflineMessage(state, reason);
    605     return;
    606   }
    607 
    608   // Reload frame if network state is changed from {!ONLINE} -> ONLINE state.
    609   if (reason == ErrorScreenActor::ERROR_REASON_NETWORK_STATE_CHANGED &&
    610       from_not_online_to_online_transition) {
    611     // Schedules a immediate retry.
    612     LOG(WARNING) << "Retry frame load since network has been changed.";
    613     reload_gaia.ScheduleCall();
    614   }
    615 
    616   if (reason == ErrorScreenActor::ERROR_REASON_PROXY_CONFIG_CHANGED &&
    617       error_screen_should_overlay) {
    618     // Schedules a immediate retry.
    619     LOG(WARNING) << "Retry frameload since proxy settings has been changed.";
    620     reload_gaia.ScheduleCall();
    621   }
    622 
    623   if (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
    624       !IsProxyError(state, reason, FrameError())) {
    625     LOG(WARNING) << "Retry frame load due to reason: "
    626                  << ErrorScreenActor::ErrorReasonString(reason);
    627     reload_gaia.ScheduleCall();
    628   }
    629 
    630   if (is_gaia_loading_timeout) {
    631     LOG(WARNING) << "Retry frame load due to loading timeout.";
    632     reload_gaia.ScheduleCall();
    633   }
    634 
    635   if ((!is_online || is_gaia_loading_timeout || is_gaia_error) &&
    636       !offline_login_active_) {
    637     SetupAndShowOfflineMessage(state, reason);
    638   } else {
    639     HideOfflineMessage(state, reason);
    640   }
    641 }
    642 
    643 void SigninScreenHandler::SetupAndShowOfflineMessage(
    644     NetworkStateInformer:: State state,
    645     ErrorScreenActor::ErrorReason reason) {
    646   const std::string network_path = network_state_informer_->network_path();
    647   const bool is_behind_captive_portal = IsBehindCaptivePortal(state, reason);
    648   const bool is_proxy_error = IsProxyError(state, reason, FrameError());
    649   const bool is_gaia_loading_timeout =
    650       (reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
    651 
    652   if (is_proxy_error) {
    653     error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PROXY,
    654                                        std::string());
    655   } else if (is_behind_captive_portal) {
    656     // Do not bother a user with obsessive captive portal showing. This
    657     // check makes captive portal being shown only once: either when error
    658     // screen is shown for the first time or when switching from another
    659     // error screen (offline, proxy).
    660     if (IsGaiaVisible() ||
    661         (error_screen_actor_->error_state() !=
    662          ErrorScreen::ERROR_STATE_PORTAL)) {
    663       error_screen_actor_->FixCaptivePortal();
    664     }
    665     const std::string network_name = GetNetworkName(network_path);
    666     error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_PORTAL,
    667                                        network_name);
    668   } else if (is_gaia_loading_timeout) {
    669     error_screen_actor_->SetErrorState(
    670         ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT, std::string());
    671   } else {
    672     error_screen_actor_->SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE,
    673                                        std::string());
    674   }
    675 
    676   const bool guest_signin_allowed = IsGuestSigninAllowed() &&
    677       IsSigninScreenError(error_screen_actor_->error_state());
    678   error_screen_actor_->AllowGuestSignin(guest_signin_allowed);
    679 
    680   const bool offline_login_allowed = IsOfflineLoginAllowed() &&
    681       IsSigninScreenError(error_screen_actor_->error_state()) &&
    682       error_screen_actor_->error_state() !=
    683       ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT;
    684   error_screen_actor_->AllowOfflineLogin(offline_login_allowed);
    685 
    686   if (GetCurrentScreen() != OobeUI::SCREEN_ERROR_MESSAGE) {
    687     base::DictionaryValue params;
    688     const std::string network_type = network_state_informer_->network_type();
    689     params.SetString("lastNetworkType", network_type);
    690     error_screen_actor_->SetUIState(ErrorScreen::UI_STATE_SIGNIN);
    691     error_screen_actor_->Show(OobeUI::SCREEN_GAIA_SIGNIN, &params);
    692   }
    693 }
    694 
    695 void SigninScreenHandler::HideOfflineMessage(
    696     NetworkStateInformer::State state,
    697     ErrorScreenActor::ErrorReason reason) {
    698   if (!IsSigninScreenHiddenByError())
    699     return;
    700 
    701   error_screen_actor_->Hide();
    702 
    703   // Forces a reload for Gaia screen on hiding error message.
    704   if (IsGaiaVisible() || IsGaiaHiddenByError())
    705     ReloadGaia(false);
    706 }
    707 
    708 void SigninScreenHandler::ReloadGaia(bool force_reload) {
    709   gaia_screen_handler_->ReloadGaia(force_reload);
    710 }
    711 
    712 void SigninScreenHandler::Initialize() {
    713   // If delegate_ is NULL here (e.g. WebUIScreenLocker has been destroyed),
    714   // don't do anything, just return.
    715   if (!delegate_)
    716     return;
    717 
    718   if (show_on_init_) {
    719     show_on_init_ = false;
    720     ShowImpl();
    721   }
    722 }
    723 
    724 gfx::NativeWindow SigninScreenHandler::GetNativeWindow() {
    725   if (native_window_delegate_)
    726     return native_window_delegate_->GetNativeWindow();
    727   return NULL;
    728 }
    729 
    730 void SigninScreenHandler::RegisterMessages() {
    731   AddCallback("authenticateUser", &SigninScreenHandler::HandleAuthenticateUser);
    732   AddCallback("attemptUnlock", &SigninScreenHandler::HandleAttemptUnlock);
    733   AddCallback("getUsers", &SigninScreenHandler::HandleGetUsers);
    734   AddCallback("launchDemoUser", &SigninScreenHandler::HandleLaunchDemoUser);
    735   AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito);
    736   AddCallback("showSupervisedUserCreationScreen",
    737               &SigninScreenHandler::HandleShowSupervisedUserCreationScreen);
    738   AddCallback("launchPublicSession",
    739               &SigninScreenHandler::HandleLaunchPublicSession);
    740   AddRawCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin);
    741   AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem);
    742   AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser);
    743   AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem);
    744   AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper);
    745   AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser);
    746   AddCallback("toggleEnrollmentScreen",
    747               &SigninScreenHandler::HandleToggleEnrollmentScreen);
    748   AddCallback("toggleKioskEnableScreen",
    749               &SigninScreenHandler::HandleToggleKioskEnableScreen);
    750   AddCallback("createAccount", &SigninScreenHandler::HandleCreateAccount);
    751   AddCallback("accountPickerReady",
    752               &SigninScreenHandler::HandleAccountPickerReady);
    753   AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady);
    754   AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser);
    755   AddCallback("openProxySettings",
    756               &SigninScreenHandler::HandleOpenProxySettings);
    757   AddCallback("loginVisible", &SigninScreenHandler::HandleLoginVisible);
    758   AddCallback("cancelPasswordChangedFlow",
    759               &SigninScreenHandler::HandleCancelPasswordChangedFlow);
    760   AddCallback("cancelUserAdding",
    761               &SigninScreenHandler::HandleCancelUserAdding);
    762   AddCallback("migrateUserData", &SigninScreenHandler::HandleMigrateUserData);
    763   AddCallback("resyncUserData", &SigninScreenHandler::HandleResyncUserData);
    764   AddCallback("loginUIStateChanged",
    765               &SigninScreenHandler::HandleLoginUIStateChanged);
    766   AddCallback("unlockOnLoginSuccess",
    767               &SigninScreenHandler::HandleUnlockOnLoginSuccess);
    768   AddCallback("showLoadingTimeoutError",
    769               &SigninScreenHandler::HandleShowLoadingTimeoutError);
    770   AddCallback("updateOfflineLogin",
    771               &SigninScreenHandler::HandleUpdateOfflineLogin);
    772   AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
    773   AddCallback("hardlockPod", &SigninScreenHandler::HandleHardlockPod);
    774   AddCallback("retrieveAuthenticatedUserEmail",
    775               &SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail);
    776   AddCallback("getPublicSessionKeyboardLayouts",
    777               &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
    778   AddCallback("cancelConsumerManagementEnrollment",
    779               &SigninScreenHandler::HandleCancelConsumerManagementEnrollment);
    780   AddCallback("getTouchViewState",
    781               &SigninScreenHandler::HandleGetTouchViewState);
    782 
    783 
    784   // This message is sent by the kiosk app menu, but is handled here
    785   // so we can tell the delegate to launch the app.
    786   AddCallback("launchKioskApp", &SigninScreenHandler::HandleLaunchKioskApp);
    787 }
    788 
    789 void SigninScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
    790   registry->RegisterDictionaryPref(prefs::kUsersLRUInputMethod);
    791 }
    792 
    793 void SigninScreenHandler::OnCurrentScreenChanged(OobeUI::Screen current_screen,
    794                                                  OobeUI::Screen new_screen) {
    795   if (new_screen == OobeUI::SCREEN_ACCOUNT_PICKER) {
    796     // Restore active IME state if returning to user pod row screen.
    797     input_method::InputMethodManager::Get()->SetState(ime_state_);
    798   }
    799 }
    800 
    801 std::string SigninScreenHandler::GetUserLRUInputMethod(
    802     const std::string& username) const {
    803   PrefService* const local_state = g_browser_process->local_state();
    804   const base::DictionaryValue* users_lru_input_methods =
    805       local_state->GetDictionary(prefs::kUsersLRUInputMethod);
    806 
    807   if (users_lru_input_methods == NULL) {
    808     DLOG(WARNING) << "GetUserLRUInputMethod('" << username
    809                   << "'): no kUsersLRUInputMethod";
    810     return std::string();
    811   }
    812 
    813   std::string input_method;
    814 
    815   if (!users_lru_input_methods->GetStringWithoutPathExpansion(username,
    816                                                               &input_method)) {
    817     DVLOG(0) << "GetUserLRUInputMethod('" << username
    818              << "'): no input method for this user";
    819     return std::string();
    820   }
    821 
    822   return input_method;
    823 }
    824 
    825 void SigninScreenHandler::HandleGetUsers() {
    826   if (delegate_)
    827     delegate_->HandleGetUsers();
    828 }
    829 
    830 void SigninScreenHandler::ClearAndEnablePassword() {
    831   core_oobe_actor_->ResetSignInUI(false);
    832 }
    833 
    834 void SigninScreenHandler::ClearUserPodPassword() {
    835   core_oobe_actor_->ClearUserPodPassword();
    836 }
    837 
    838 void SigninScreenHandler::RefocusCurrentPod() {
    839   core_oobe_actor_->RefocusCurrentPod();
    840 }
    841 
    842 void SigninScreenHandler::OnUserRemoved(const std::string& username) {
    843   CallJS("login.AccountPickerScreen.removeUser", username);
    844   if (delegate_->GetUsers().empty())
    845     OnShowAddUser();
    846 }
    847 
    848 void SigninScreenHandler::OnUserImageChanged(const user_manager::User& user) {
    849   if (page_is_ready())
    850     CallJS("login.AccountPickerScreen.updateUserImage", user.email());
    851 }
    852 
    853 void SigninScreenHandler::OnPreferencesChanged() {
    854   // Make sure that one of the login UI is fully functional now, otherwise
    855   // preferences update would be picked up next time it will be shown.
    856   if (!webui_visible_) {
    857     LOG(WARNING) << "Login UI is not active - postponed prefs change.";
    858     preferences_changed_delayed_ = true;
    859     return;
    860   }
    861 
    862   if (delegate_ && !delegate_->IsShowUsers()) {
    863     HandleShowAddUser(NULL);
    864   } else {
    865     if (delegate_)
    866       delegate_->HandleGetUsers();
    867     UpdateUIState(UI_STATE_ACCOUNT_PICKER, NULL);
    868   }
    869   preferences_changed_delayed_ = false;
    870 }
    871 
    872 void SigninScreenHandler::ResetSigninScreenHandlerDelegate() {
    873   SetDelegate(NULL);
    874 }
    875 
    876 void SigninScreenHandler::ShowError(int login_attempts,
    877                                     const std::string& error_text,
    878                                     const std::string& help_link_text,
    879                                     HelpAppLauncher::HelpTopic help_topic_id) {
    880   core_oobe_actor_->ShowSignInError(login_attempts, error_text, help_link_text,
    881                                     help_topic_id);
    882 }
    883 
    884 void SigninScreenHandler::ShowErrorScreen(LoginDisplay::SigninError error_id) {
    885   switch (error_id) {
    886     case LoginDisplay::TPM_ERROR:
    887       core_oobe_actor_->ShowTpmError();
    888       break;
    889     default:
    890       NOTREACHED() << "Unknown sign in error";
    891       break;
    892   }
    893 }
    894 
    895 void SigninScreenHandler::ShowSigninUI(const std::string& email) {
    896   core_oobe_actor_->ShowSignInUI(email);
    897 }
    898 
    899 void SigninScreenHandler::ShowGaiaPasswordChanged(const std::string& username) {
    900   gaia_screen_handler_->PasswordChangedFor(username);
    901   gaia_screen_handler_->PopulateEmail(username);
    902   core_oobe_actor_->ShowSignInUI(username);
    903   CallJS("login.setAuthType",
    904          username,
    905          static_cast<int>(ONLINE_SIGN_IN),
    906          base::StringValue(""));
    907 }
    908 
    909 void SigninScreenHandler::ShowPasswordChangedDialog(bool show_password_error) {
    910   core_oobe_actor_->ShowPasswordChangedScreen(show_password_error);
    911 }
    912 
    913 void SigninScreenHandler::ShowSigninScreenForCreds(
    914     const std::string& username,
    915     const std::string& password) {
    916   DCHECK(gaia_screen_handler_);
    917   gaia_screen_handler_->ShowSigninScreenForCreds(username, password);
    918 }
    919 
    920 void SigninScreenHandler::SetPublicSessionDisplayName(
    921       const std::string& user_id,
    922       const std::string& display_name) {
    923   CallJS("login.AccountPickerScreen.setPublicSessionDisplayName",
    924          user_id,
    925          display_name);
    926 }
    927 
    928 void SigninScreenHandler::SetPublicSessionLocales(
    929     const std::string& user_id,
    930     scoped_ptr<base::ListValue> locales,
    931     const std::string& default_locale,
    932     bool multipleRecommendedLocales) {
    933   CallJS("login.AccountPickerScreen.setPublicSessionLocales",
    934          user_id,
    935          *locales,
    936          default_locale,
    937          multipleRecommendedLocales);
    938 }
    939 
    940 void SigninScreenHandler::Observe(int type,
    941                                   const content::NotificationSource& source,
    942                                   const content::NotificationDetails& details) {
    943   switch (type) {
    944     case chrome::NOTIFICATION_AUTH_NEEDED: {
    945       has_pending_auth_ui_ = true;
    946       break;
    947     }
    948     case chrome::NOTIFICATION_AUTH_SUPPLIED:
    949       has_pending_auth_ui_ = false;
    950       // Reload auth extension as proxy credentials are supplied.
    951       if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
    952         ReloadGaia(true);
    953       update_state_closure_.Cancel();
    954       break;
    955     case chrome::NOTIFICATION_AUTH_CANCELLED: {
    956       // Don't reload auth extension if proxy auth dialog was cancelled.
    957       has_pending_auth_ui_ = false;
    958       update_state_closure_.Cancel();
    959       break;
    960     }
    961     default:
    962       NOTREACHED() << "Unexpected notification " << type;
    963   }
    964 }
    965 
    966 void SigninScreenHandler::ShowBannerMessage(const base::string16& message) {
    967   CallJS("login.AccountPickerScreen.showBannerMessage", message);
    968 }
    969 
    970 void SigninScreenHandler::ShowUserPodCustomIcon(
    971     const std::string& username,
    972     const ScreenlockBridge::UserPodCustomIconOptions& icon_options) {
    973   scoped_ptr<base::DictionaryValue> icon = icon_options.ToDictionaryValue();
    974   if (!icon || icon->empty())
    975     return;
    976   CallJS("login.AccountPickerScreen.showUserPodCustomIcon", username, *icon);
    977 }
    978 
    979 void SigninScreenHandler::HideUserPodCustomIcon(const std::string& username) {
    980   CallJS("login.AccountPickerScreen.hideUserPodCustomIcon", username);
    981 }
    982 
    983 void SigninScreenHandler::EnableInput() {
    984   // Only for lock screen at the moment.
    985   ScreenLocker::default_screen_locker()->EnableInput();
    986 }
    987 
    988 void SigninScreenHandler::SetAuthType(
    989     const std::string& username,
    990     ScreenlockBridge::LockHandler::AuthType auth_type,
    991     const base::string16& initial_value) {
    992   if (delegate_->GetAuthType(username) ==
    993           ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD)
    994     return;
    995 
    996   delegate_->SetAuthType(username, auth_type);
    997 
    998   CallJS("login.AccountPickerScreen.setAuthType",
    999          username,
   1000          static_cast<int>(auth_type),
   1001          base::StringValue(initial_value));
   1002 }
   1003 
   1004 ScreenlockBridge::LockHandler::AuthType SigninScreenHandler::GetAuthType(
   1005     const std::string& username) const {
   1006   return delegate_->GetAuthType(username);
   1007 }
   1008 
   1009 void SigninScreenHandler::Unlock(const std::string& user_email) {
   1010   DCHECK(ScreenLocker::default_screen_locker());
   1011   ScreenLocker::Hide();
   1012 }
   1013 
   1014 void SigninScreenHandler::AttemptEasySignin(const std::string& user_email,
   1015                                             const std::string& secret,
   1016                                             const std::string& key_label) {
   1017   DCHECK(!ScreenLocker::default_screen_locker());
   1018   if (!delegate_)
   1019     return;
   1020 
   1021   UserContext user_context(user_email);
   1022   user_context.SetAuthFlow(UserContext::AUTH_FLOW_EASY_UNLOCK);
   1023   user_context.SetKey(Key(secret));
   1024   user_context.GetKey()->SetLabel(key_label);
   1025 
   1026   // TODO(tbarzic): Handle empty secret. The delegate will end up ignoring login
   1027   // attempt if the key is not set, and the UI will remain disabled.
   1028   DCHECK(!secret.empty());
   1029 
   1030   delegate_->Login(user_context, SigninSpecifics());
   1031 }
   1032 
   1033 void SigninScreenHandler::OnMaximizeModeStarted() {
   1034   CallJS("login.AccountPickerScreen.setTouchViewState", true);
   1035 }
   1036 
   1037 void SigninScreenHandler::OnMaximizeModeEnded() {
   1038   CallJS("login.AccountPickerScreen.setTouchViewState", false);
   1039 }
   1040 
   1041 bool SigninScreenHandler::ShouldLoadGaia() const {
   1042   // Fetching of the extension is not started before account picker page is
   1043   // loaded because it can affect the loading speed.
   1044   // Do not load the extension for the screen locker, see crosbug.com/25018.
   1045   return !ScreenLocker::default_screen_locker() &&
   1046          is_account_picker_showing_first_time_;
   1047 }
   1048 
   1049 // Update keyboard layout to least recently used by the user.
   1050 void SigninScreenHandler::SetUserInputMethod(
   1051     const std::string& username,
   1052     input_method::InputMethodManager::State* ime_state) {
   1053   bool succeed = false;
   1054 
   1055   const std::string input_method = GetUserLRUInputMethod(username);
   1056 
   1057   if (!input_method.empty())
   1058     succeed = SetUserInputMethodImpl(username, input_method, ime_state);
   1059 
   1060   // This is also a case when LRU layout is set only for a few local users,
   1061   // thus others need to be switched to default locale.
   1062   // Otherwise they will end up using another user's locale to log in.
   1063   if (!succeed) {
   1064     DVLOG(0) << "SetUserInputMethod('" << username
   1065                << "'): failed to set user layout. Switching to default.";
   1066 
   1067     ime_state->SetInputMethodLoginDefault();
   1068   }
   1069 }
   1070 
   1071 
   1072 void SigninScreenHandler::UserSettingsChanged() {
   1073   DCHECK(gaia_screen_handler_);
   1074   GaiaContext context;
   1075   if (delegate_)
   1076     context.has_users = !delegate_->GetUsers().empty();
   1077   gaia_screen_handler_->UpdateGaia(context);
   1078   UpdateAddButtonStatus();
   1079 }
   1080 
   1081 void SigninScreenHandler::UpdateAddButtonStatus() {
   1082   CallJS("cr.ui.login.DisplayManager.updateAddUserButtonStatus",
   1083          AllWhitelistedUsersPresent());
   1084 }
   1085 
   1086 void SigninScreenHandler::HandleAuthenticateUser(const std::string& username,
   1087                                                  const std::string& password) {
   1088   if (!delegate_)
   1089     return;
   1090   UserContext user_context(username);
   1091   user_context.SetKey(Key(password));
   1092   delegate_->Login(user_context, SigninSpecifics());
   1093 }
   1094 
   1095 void SigninScreenHandler::HandleAttemptUnlock(const std::string& username) {
   1096   EasyUnlockService* service = GetEasyUnlockServiceForUser(username);
   1097   if (!service)
   1098     return;
   1099   service->AttemptAuth(username);
   1100 }
   1101 
   1102 void SigninScreenHandler::HandleLaunchDemoUser() {
   1103   UserContext context(user_manager::USER_TYPE_RETAIL_MODE, std::string());
   1104   if (delegate_)
   1105     delegate_->Login(context, SigninSpecifics());
   1106 }
   1107 
   1108 void SigninScreenHandler::HandleLaunchIncognito() {
   1109   UserContext context(user_manager::USER_TYPE_GUEST, std::string());
   1110   if (delegate_)
   1111     delegate_->Login(context, SigninSpecifics());
   1112 }
   1113 
   1114 void SigninScreenHandler::HandleShowSupervisedUserCreationScreen() {
   1115   if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
   1116     LOG(ERROR) << "Managed users not allowed.";
   1117     return;
   1118   }
   1119   scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
   1120   LoginDisplayHostImpl::default_host()->
   1121       StartWizard(WizardController::kSupervisedUserCreationScreenName,
   1122       params.Pass());
   1123 }
   1124 
   1125 void SigninScreenHandler::HandleLaunchPublicSession(
   1126     const std::string& user_id,
   1127     const std::string& locale,
   1128     const std::string& input_method) {
   1129   if (!delegate_)
   1130     return;
   1131 
   1132   UserContext context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user_id);
   1133   context.SetPublicSessionLocale(locale),
   1134   context.SetPublicSessionInputMethod(input_method);
   1135   delegate_->Login(context, SigninSpecifics());
   1136 }
   1137 
   1138 void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) {
   1139   if (!delegate_ || delegate_->IsShowUsers()) {
   1140     NOTREACHED();
   1141     return;
   1142   }
   1143   std::string email;
   1144   args->GetString(0, &email);
   1145 
   1146   gaia_screen_handler_->PopulateEmail(email);
   1147   // Load auth extension. Parameters are: force reload, do not load extension in
   1148   // background, use offline version.
   1149   gaia_screen_handler_->LoadAuthExtension(true, false, true);
   1150   UpdateUIState(UI_STATE_GAIA_SIGNIN, NULL);
   1151 }
   1152 
   1153 void SigninScreenHandler::HandleShutdownSystem() {
   1154   ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown();
   1155 }
   1156 
   1157 void SigninScreenHandler::HandleLoadWallpaper(const std::string& email) {
   1158   if (delegate_)
   1159     delegate_->LoadWallpaper(email);
   1160 }
   1161 
   1162 void SigninScreenHandler::HandleRebootSystem() {
   1163   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
   1164 }
   1165 
   1166 void SigninScreenHandler::HandleRemoveUser(const std::string& email) {
   1167   if (!delegate_)
   1168     return;
   1169   delegate_->RemoveUser(email);
   1170   UpdateAddButtonStatus();
   1171 }
   1172 
   1173 void SigninScreenHandler::HandleShowAddUser(const base::ListValue* args) {
   1174   TRACE_EVENT_ASYNC_STEP_INTO0("ui",
   1175                                "ShowLoginWebUI",
   1176                                LoginDisplayHostImpl::kShowLoginWebUIid,
   1177                                "ShowAddUser");
   1178   std::string email;
   1179   // |args| can be null if it's OOBE.
   1180   if (args)
   1181     args->GetString(0, &email);
   1182   gaia_screen_handler_->PopulateEmail(email);
   1183   OnShowAddUser();
   1184 }
   1185 
   1186 void SigninScreenHandler::HandleToggleEnrollmentScreen() {
   1187   if (delegate_)
   1188     delegate_->ShowEnterpriseEnrollmentScreen();
   1189 }
   1190 
   1191 void SigninScreenHandler::HandleToggleKioskEnableScreen() {
   1192   policy::BrowserPolicyConnectorChromeOS* connector =
   1193       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   1194   if (delegate_ &&
   1195       !auto_enrollment_progress_subscription_ &&
   1196       !connector->IsEnterpriseManaged() &&
   1197       LoginDisplayHostImpl::default_host()) {
   1198     AutoEnrollmentController* auto_enrollment_controller =
   1199         LoginDisplayHostImpl::default_host()->GetAutoEnrollmentController();
   1200     auto_enrollment_progress_subscription_ =
   1201         auto_enrollment_controller->RegisterProgressCallback(
   1202             base::Bind(&SigninScreenHandler::ContinueKioskEnableFlow,
   1203                        weak_factory_.GetWeakPtr()));
   1204     ContinueKioskEnableFlow(auto_enrollment_controller->state());
   1205   }
   1206 }
   1207 
   1208 void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() {
   1209   policy::BrowserPolicyConnectorChromeOS* connector =
   1210       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   1211   if (delegate_ && !connector->IsEnterpriseManaged())
   1212     delegate_->ShowKioskAutolaunchScreen();
   1213 }
   1214 
   1215 void SigninScreenHandler::LoadUsers(const base::ListValue& users_list,
   1216                                     bool showGuest) {
   1217   CallJS("login.AccountPickerScreen.loadUsers",
   1218          users_list,
   1219          delegate_->IsShowGuest());
   1220 }
   1221 
   1222 void SigninScreenHandler::HandleAccountPickerReady() {
   1223   VLOG(0) << "Login WebUI >> AccountPickerReady";
   1224 
   1225   if (delegate_ && !ScreenLocker::default_screen_locker() &&
   1226       !chromeos::IsMachineHWIDCorrect() &&
   1227       !oobe_ui_) {
   1228     delegate_->ShowWrongHWIDScreen();
   1229     return;
   1230   }
   1231 
   1232   PrefService* prefs = g_browser_process->local_state();
   1233   if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
   1234     if (core_oobe_actor_) {
   1235       core_oobe_actor_->ShowDeviceResetScreen();
   1236       return;
   1237     }
   1238   }
   1239 
   1240   is_account_picker_showing_first_time_ = true;
   1241   gaia_screen_handler_->MaybePreloadAuthExtension();
   1242 
   1243   ScreenlockBridge::Get()->SetLockHandler(this);
   1244   if (ScreenLocker::default_screen_locker()) {
   1245     ScreenLocker::default_screen_locker()->delegate()->OnLockWebUIReady();
   1246   }
   1247 
   1248   if (delegate_)
   1249     delegate_->OnSigninScreenReady();
   1250 }
   1251 
   1252 void SigninScreenHandler::HandleWallpaperReady() {
   1253   if (ScreenLocker::default_screen_locker()) {
   1254     ScreenLocker::default_screen_locker()->delegate()->
   1255         OnLockBackgroundDisplayed();
   1256   }
   1257 }
   1258 
   1259 void SigninScreenHandler::HandleSignOutUser() {
   1260   if (delegate_)
   1261     delegate_->Signout();
   1262 }
   1263 
   1264 void SigninScreenHandler::HandleCreateAccount() {
   1265   if (delegate_)
   1266     delegate_->CreateAccount();
   1267 }
   1268 
   1269 void SigninScreenHandler::HandleOpenProxySettings() {
   1270   LoginDisplayHostImpl::default_host()->OpenProxySettings();
   1271 }
   1272 
   1273 void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
   1274   VLOG(1) << "Login WebUI >> loginVisible, src: " << source << ", "
   1275           << "webui_visible_: " << webui_visible_;
   1276   if (!webui_visible_) {
   1277     // There might be multiple messages from OOBE UI so send notifications after
   1278     // the first one only.
   1279     content::NotificationService::current()->Notify(
   1280         chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
   1281         content::NotificationService::AllSources(),
   1282         content::NotificationService::NoDetails());
   1283     TRACE_EVENT_ASYNC_END0(
   1284         "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid);
   1285   }
   1286   webui_visible_ = true;
   1287   if (preferences_changed_delayed_)
   1288     OnPreferencesChanged();
   1289 }
   1290 
   1291 void SigninScreenHandler::HandleCancelPasswordChangedFlow() {
   1292   gaia_screen_handler_->StartClearingCookies(
   1293       base::Bind(&SigninScreenHandler::CancelPasswordChangedFlowInternal,
   1294                  weak_factory_.GetWeakPtr()));
   1295 }
   1296 
   1297 void SigninScreenHandler::HandleCancelUserAdding() {
   1298   if (delegate_)
   1299     delegate_->CancelUserAdding();
   1300 }
   1301 
   1302 void SigninScreenHandler::HandleMigrateUserData(
   1303     const std::string& old_password) {
   1304   if (delegate_)
   1305     delegate_->MigrateUserData(old_password);
   1306 }
   1307 
   1308 void SigninScreenHandler::HandleResyncUserData() {
   1309   if (delegate_)
   1310     delegate_->ResyncUserData();
   1311 }
   1312 
   1313 void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source,
   1314                                                     bool new_value) {
   1315   VLOG(0) << "Login WebUI >> active: " << new_value << ", "
   1316             << "source: " << source;
   1317 
   1318   if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() &&
   1319       KioskAppManager::Get()->IsAutoLaunchRequested()) {
   1320     VLOG(0) << "Showing auto-launch warning";
   1321     // On slow devices, the wallpaper animation is not shown initially, so we
   1322     // must explicitly load the wallpaper. This is also the case for the
   1323     // account-picker and gaia-signin UI states.
   1324     delegate_->LoadSigninWallpaper();
   1325     HandleToggleKioskAutolaunchScreen();
   1326     return;
   1327   }
   1328 
   1329   if (source == kSourceGaiaSignin) {
   1330     ui_state_ = UI_STATE_GAIA_SIGNIN;
   1331   } else if (source == kSourceAccountPicker) {
   1332     ui_state_ = UI_STATE_ACCOUNT_PICKER;
   1333   } else {
   1334     NOTREACHED();
   1335     return;
   1336   }
   1337 }
   1338 
   1339 void SigninScreenHandler::HandleUnlockOnLoginSuccess() {
   1340   DCHECK(user_manager::UserManager::Get()->IsUserLoggedIn());
   1341   if (ScreenLocker::default_screen_locker())
   1342     ScreenLocker::default_screen_locker()->UnlockOnLoginSuccess();
   1343 }
   1344 
   1345 void SigninScreenHandler::HandleShowLoadingTimeoutError() {
   1346   UpdateState(ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
   1347 }
   1348 
   1349 void SigninScreenHandler::HandleUpdateOfflineLogin(bool offline_login_active) {
   1350   offline_login_active_ = offline_login_active;
   1351 }
   1352 
   1353 void SigninScreenHandler::HandleFocusPod(const std::string& user_id) {
   1354   SetUserInputMethod(user_id, ime_state_.get());
   1355 #if !defined(USE_ATHENA)
   1356   // TODO(dpolukhin):  crbug.com/408734.
   1357   WallpaperManager::Get()->SetUserWallpaperDelayed(user_id);
   1358 #endif
   1359   ScreenlockBridge::Get()->SetFocusedUser(user_id);
   1360   if (!test_focus_pod_callback_.is_null())
   1361     test_focus_pod_callback_.Run();
   1362 }
   1363 
   1364 void SigninScreenHandler::HandleHardlockPod(const std::string& user_id) {
   1365   SetAuthType(user_id,
   1366               ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
   1367               base::string16());
   1368   EasyUnlockService* service = GetEasyUnlockServiceForUser(user_id);
   1369   if (!service)
   1370     return;
   1371   service->SetHardlockState(EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
   1372 }
   1373 
   1374 void SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail(
   1375     double attempt_token) {
   1376   // TODO(antrim) : move GaiaSigninScreen dependency to GaiaSigninScreen.
   1377   email_retriever_.reset(new AuthenticatedUserEmailRetriever(
   1378       base::Bind(&SigninScreenHandler::CallJS<double, std::string>,
   1379                  base::Unretained(this),
   1380                  "login.GaiaSigninScreen.setAuthenticatedUserEmail",
   1381                  attempt_token),
   1382       Profile::FromWebUI(web_ui())->GetRequestContext()));
   1383 }
   1384 
   1385 void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
   1386     const std::string& user_id,
   1387     const std::string& locale) {
   1388   GetKeyboardLayoutsForLocale(
   1389       base::Bind(&SigninScreenHandler::SendPublicSessionKeyboardLayouts,
   1390                  weak_factory_.GetWeakPtr(),
   1391                  user_id,
   1392                  locale),
   1393       locale);
   1394 }
   1395 
   1396 void SigninScreenHandler::SendPublicSessionKeyboardLayouts(
   1397     const std::string& user_id,
   1398     const std::string& locale,
   1399     scoped_ptr<base::ListValue> keyboard_layouts) {
   1400   CallJS("login.AccountPickerScreen.setPublicSessionKeyboardLayouts",
   1401          user_id,
   1402          locale,
   1403          *keyboard_layouts);
   1404 }
   1405 
   1406 void SigninScreenHandler::HandleLaunchKioskApp(const std::string& app_id,
   1407                                                bool diagnostic_mode) {
   1408   UserContext context(user_manager::USER_TYPE_KIOSK_APP, app_id);
   1409   SigninSpecifics specifics;
   1410   specifics.kiosk_diagnostic_mode = diagnostic_mode;
   1411   if (delegate_)
   1412     delegate_->Login(context, specifics);
   1413 }
   1414 
   1415 void SigninScreenHandler::HandleCancelConsumerManagementEnrollment() {
   1416   policy::ConsumerManagementService* consumer_management =
   1417       g_browser_process->platform_part()->browser_policy_connector_chromeos()->
   1418           GetConsumerManagementService();
   1419   CHECK(consumer_management);
   1420   consumer_management->SetEnrollmentStage(
   1421       policy::ConsumerManagementService::ENROLLMENT_STAGE_CANCELED);
   1422   is_enrolling_consumer_management_ = false;
   1423   ShowImpl();
   1424 }
   1425 
   1426 void SigninScreenHandler::HandleGetTouchViewState() {
   1427   if (max_mode_delegate_) {
   1428     CallJS("login.AccountPickerScreen.setTouchViewState",
   1429            max_mode_delegate_->IsMaximizeModeEnabled());
   1430   }
   1431 }
   1432 
   1433 bool SigninScreenHandler::AllWhitelistedUsersPresent() {
   1434   CrosSettings* cros_settings = CrosSettings::Get();
   1435   bool allow_new_user = false;
   1436   cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
   1437   if (allow_new_user)
   1438     return false;
   1439   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   1440   const user_manager::UserList& users = user_manager->GetUsers();
   1441   if (!delegate_ || users.size() > kMaxUsers) {
   1442     return false;
   1443   }
   1444   const base::ListValue* whitelist = NULL;
   1445   if (!cros_settings->GetList(kAccountsPrefUsers, &whitelist) || !whitelist)
   1446     return false;
   1447   for (size_t i = 0; i < whitelist->GetSize(); ++i) {
   1448     std::string whitelisted_user;
   1449     // NB: Wildcards in the whitelist are also detected as not present here.
   1450     if (!whitelist->GetString(i, &whitelisted_user) ||
   1451         !user_manager->IsKnownUser(whitelisted_user)) {
   1452       return false;
   1453     }
   1454   }
   1455   return true;
   1456 }
   1457 
   1458 void SigninScreenHandler::CancelPasswordChangedFlowInternal() {
   1459   if (delegate_) {
   1460     ShowImpl();
   1461     delegate_->CancelPasswordChangedFlow();
   1462   }
   1463 }
   1464 
   1465 OobeUI* SigninScreenHandler::GetOobeUI() const {
   1466   return static_cast<OobeUI*>(web_ui()->GetController());
   1467 }
   1468 
   1469 EasyUnlockService* SigninScreenHandler::GetEasyUnlockServiceForUser(
   1470       const std::string& username) const {
   1471   if (!ScreenLocker::default_screen_locker() &&
   1472       GetOobeUI()->display_type() != OobeUI::kLoginDisplay)
   1473     return NULL;
   1474 
   1475   const user_manager::User* unlock_user = NULL;
   1476   const user_manager::UserList& users = delegate_->GetUsers();
   1477   for (user_manager::UserList::const_iterator it = users.begin();
   1478        it != users.end();
   1479        ++it) {
   1480     if ((*it)->email() == username) {
   1481       unlock_user = *it;
   1482       break;
   1483     }
   1484   }
   1485   if (!unlock_user)
   1486     return NULL;
   1487 
   1488   ProfileHelper* profile_helper = ProfileHelper::Get();
   1489   Profile* profile = profile_helper->GetProfileByUser(unlock_user);
   1490 
   1491   // The user profile should exists if and only if this is lock screen.
   1492   DCHECK_NE(!profile, !ScreenLocker::default_screen_locker());
   1493 
   1494   if (!profile)
   1495     profile = profile_helper->GetSigninProfile();
   1496 
   1497   return EasyUnlockService::Get(profile);
   1498 }
   1499 
   1500 OobeUI::Screen SigninScreenHandler::GetCurrentScreen() const {
   1501   OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
   1502   OobeUI* oobe_ui = GetOobeUI();
   1503   if (oobe_ui)
   1504     screen = oobe_ui->current_screen();
   1505   return screen;
   1506 }
   1507 
   1508 bool SigninScreenHandler::IsGaiaVisible() const {
   1509   return IsSigninScreen(GetCurrentScreen()) &&
   1510       ui_state_ == UI_STATE_GAIA_SIGNIN;
   1511 }
   1512 
   1513 bool SigninScreenHandler::IsGaiaHiddenByError() const {
   1514   return IsSigninScreenHiddenByError() &&
   1515       ui_state_ == UI_STATE_GAIA_SIGNIN;
   1516 }
   1517 
   1518 bool SigninScreenHandler::IsSigninScreenHiddenByError() const {
   1519   return (GetCurrentScreen() == OobeUI::SCREEN_ERROR_MESSAGE) &&
   1520       (IsSigninScreen(error_screen_actor_->parent_screen()));
   1521 }
   1522 
   1523 bool SigninScreenHandler::IsGuestSigninAllowed() const {
   1524   CrosSettings* cros_settings = CrosSettings::Get();
   1525   if (!cros_settings)
   1526     return false;
   1527   bool allow_guest;
   1528   cros_settings->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
   1529   return allow_guest;
   1530 }
   1531 
   1532 bool SigninScreenHandler::IsOfflineLoginAllowed() const {
   1533   CrosSettings* cros_settings = CrosSettings::Get();
   1534   if (!cros_settings)
   1535     return false;
   1536 
   1537   // Offline login is allowed only when user pods are hidden.
   1538   bool show_pods;
   1539   cros_settings->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_pods);
   1540   return !show_pods;
   1541 }
   1542 
   1543 void SigninScreenHandler::ContinueKioskEnableFlow(
   1544     policy::AutoEnrollmentState state) {
   1545   // Do not proceed with kiosk enable when auto enroll will be enforced.
   1546   // TODO(xiyuan): Add an error UI feedkback so user knows what happens.
   1547   switch (state) {
   1548     case policy::AUTO_ENROLLMENT_STATE_IDLE:
   1549     case policy::AUTO_ENROLLMENT_STATE_PENDING:
   1550     case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR:
   1551       // Wait for the next callback.
   1552       return;
   1553     case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT:
   1554       // Auto-enrollment is on.
   1555       LOG(WARNING) << "Kiosk enable flow aborted because auto enrollment is "
   1556                       "going to be enforced.";
   1557       if (!kiosk_enable_flow_aborted_callback_for_test_.is_null())
   1558         kiosk_enable_flow_aborted_callback_for_test_.Run();
   1559       break;
   1560     case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR:
   1561     case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT:
   1562       // Auto-enrollment not applicable.
   1563       if (delegate_)
   1564         delegate_->ShowKioskEnableScreen();
   1565       break;
   1566   }
   1567   auto_enrollment_progress_subscription_.reset();
   1568 }
   1569 
   1570 void SigninScreenHandler::OnShowAddUser() {
   1571   is_account_picker_showing_first_time_ = false;
   1572   DCHECK(gaia_screen_handler_);
   1573   gaia_screen_handler_->ShowGaia(is_enrolling_consumer_management_);
   1574 }
   1575 
   1576 GaiaScreenHandler::FrameState SigninScreenHandler::FrameState() const {
   1577   DCHECK(gaia_screen_handler_);
   1578   return gaia_screen_handler_->frame_state();
   1579 }
   1580 
   1581 net::Error SigninScreenHandler::FrameError() const {
   1582   DCHECK(gaia_screen_handler_);
   1583   return gaia_screen_handler_->frame_error();
   1584 }
   1585 
   1586 void SigninScreenHandler::OnCapsLockChanged(bool enabled) {
   1587   caps_lock_enabled_ = enabled;
   1588   if (page_is_ready())
   1589     CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_);
   1590 }
   1591 
   1592 }  // namespace chromeos
   1593