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