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