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#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_SIGNIN_SCREEN_HANDLER_H_
6#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_SIGNIN_SCREEN_HANDLER_H_
7
8#include <map>
9#include <set>
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/callback.h"
14#include "base/compiler_specific.h"
15#include "base/containers/hash_tables.h"
16#include "base/memory/ref_counted.h"
17#include "base/memory/scoped_ptr.h"
18#include "base/memory/weak_ptr.h"
19#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h"
20#include "chrome/browser/chromeos/login/screens/error_screen_actor.h"
21#include "chrome/browser/chromeos/login/signin_specifics.h"
22#include "chrome/browser/chromeos/login/ui/login_display.h"
23#include "chrome/browser/chromeos/settings/cros_settings.h"
24#include "chrome/browser/signin/screenlock_bridge.h"
25#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
26#include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
27#include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
28#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
29#include "chrome/browser/ui/webui/chromeos/touch_view_controller_delegate.h"
30#include "chromeos/ime/ime_keyboard.h"
31#include "chromeos/ime/input_method_manager.h"
32#include "chromeos/network/portal_detector/network_portal_detector.h"
33#include "components/user_manager/user_manager.h"
34#include "content/public/browser/notification_observer.h"
35#include "content/public/browser/notification_registrar.h"
36#include "content/public/browser/web_ui.h"
37#include "net/base/net_errors.h"
38#include "ui/events/event_handler.h"
39
40class EasyUnlockService;
41
42namespace base {
43class DictionaryValue;
44class ListValue;
45}
46
47namespace chromeos {
48
49class AuthenticatedUserEmailRetriever;
50class CaptivePortalWindowProxy;
51class CoreOobeActor;
52class GaiaScreenHandler;
53class NativeWindowDelegate;
54class SupervisedUserCreationScreenHandler;
55class User;
56class UserContext;
57
58// Helper class to pass initial parameters to the login screen.
59class LoginScreenContext {
60 public:
61  LoginScreenContext();
62  explicit LoginScreenContext(const base::ListValue* args);
63
64  void set_email(const std::string& email) { email_ = email; }
65  const std::string& email() const { return email_; }
66
67  void set_oobe_ui(bool oobe_ui) { oobe_ui_ = oobe_ui; }
68  bool oobe_ui() const { return oobe_ui_; }
69
70 private:
71  void Init();
72
73  std::string email_;
74  bool oobe_ui_;
75};
76
77// An interface for WebUILoginDisplay to call SigninScreenHandler.
78class LoginDisplayWebUIHandler {
79 public:
80  virtual void ClearAndEnablePassword() = 0;
81  virtual void ClearUserPodPassword() = 0;
82  virtual void OnUserRemoved(const std::string& username) = 0;
83  virtual void OnUserImageChanged(const user_manager::User& user) = 0;
84  virtual void OnPreferencesChanged() = 0;
85  virtual void ResetSigninScreenHandlerDelegate() = 0;
86  virtual void ShowError(int login_attempts,
87                         const std::string& error_text,
88                         const std::string& help_link_text,
89                         HelpAppLauncher::HelpTopic help_topic_id) = 0;
90  virtual void ShowErrorScreen(LoginDisplay::SigninError error_id) = 0;
91  virtual void ShowGaiaPasswordChanged(const std::string& username) = 0;
92  virtual void ShowSigninUI(const std::string& email) = 0;
93  virtual void ShowPasswordChangedDialog(bool show_password_error) = 0;
94  // Show sign-in screen for the given credentials.
95  virtual void ShowSigninScreenForCreds(const std::string& username,
96                                        const std::string& password) = 0;
97  virtual void LoadUsers(const base::ListValue& users_list,
98                         bool show_guest) = 0;
99  virtual void SetPublicSessionDisplayName(const std::string& user_id,
100                                           const std::string& display_name) = 0;
101  virtual void SetPublicSessionLocales(const std::string& user_id,
102                                       scoped_ptr<base::ListValue> locales,
103                                       const std::string& default_locale,
104                                       bool multipleRecommendedLocales) = 0;
105
106 protected:
107  virtual ~LoginDisplayWebUIHandler() {}
108};
109
110// An interface for SigninScreenHandler to call WebUILoginDisplay.
111class SigninScreenHandlerDelegate {
112 public:
113  // --------------- Password change flow methods.
114  // Cancels current password changed flow.
115  virtual void CancelPasswordChangedFlow() = 0;
116
117  // Decrypt cryptohome using user provided |old_password|
118  // and migrate to new password.
119  virtual void MigrateUserData(const std::string& old_password) = 0;
120
121  // Ignore password change, remove existing cryptohome and
122  // force full sync of user data.
123  virtual void ResyncUserData() = 0;
124
125  // --------------- Sign in/out methods.
126  // Sign in using username and password specified as a part of |user_context|.
127  // Used for both known and new users.
128  virtual void Login(const UserContext& user_context,
129                     const SigninSpecifics& specifics) = 0;
130
131  // Sign in as guest to create a new Google account.
132  virtual void CreateAccount() = 0;
133
134  // Returns true if sign in is in progress.
135  virtual bool IsSigninInProgress() const = 0;
136
137  // Signs out if the screen is currently locked.
138  virtual void Signout() = 0;
139
140  // --------------- Account creation methods.
141  // Confirms sign up by provided credentials in |user_context|.
142  // Used for new user login via GAIA extension.
143  virtual void CompleteLogin(const UserContext& user_context) = 0;
144
145  // --------------- Shared with login display methods.
146  // Notify the delegate when the sign-in UI is finished loading.
147  virtual void OnSigninScreenReady() = 0;
148
149  // Shows Enterprise Enrollment screen.
150  virtual void ShowEnterpriseEnrollmentScreen() = 0;
151
152  // Shows Kiosk Enable screen.
153  virtual void ShowKioskEnableScreen() = 0;
154
155  // Shows Reset screen.
156  virtual void ShowKioskAutolaunchScreen() = 0;
157
158  // Show wrong hwid screen.
159  virtual void ShowWrongHWIDScreen() = 0;
160
161  // Sets the displayed email for the next login attempt. If it succeeds,
162  // user's displayed email value will be updated to |email|.
163  virtual void SetDisplayEmail(const std::string& email) = 0;
164
165  // --------------- Rest of the methods.
166  // Cancels user adding.
167  virtual void CancelUserAdding() = 0;
168
169  // Load wallpaper for given |username|.
170  virtual void LoadWallpaper(const std::string& username) = 0;
171
172  // Loads the default sign-in wallpaper.
173  virtual void LoadSigninWallpaper() = 0;
174
175  // Attempts to remove given user.
176  virtual void RemoveUser(const std::string& username) = 0;
177
178  // Let the delegate know about the handler it is supposed to be using.
179  virtual void SetWebUIHandler(LoginDisplayWebUIHandler* webui_handler) = 0;
180
181  // Returns users list to be shown.
182  virtual const user_manager::UserList& GetUsers() const = 0;
183
184  // Whether login as guest is available.
185  virtual bool IsShowGuest() const = 0;
186
187  // Weather to show the user pods or only GAIA sign in.
188  // Public sessions are always shown.
189  virtual bool IsShowUsers() const = 0;
190
191  // Whether user sign in has completed.
192  virtual bool IsUserSigninCompleted() const = 0;
193
194  // Request to (re)load user list.
195  virtual void HandleGetUsers() = 0;
196
197  // Set authentication type (for easier unlocking).
198  virtual void SetAuthType(
199      const std::string& username,
200      ScreenlockBridge::LockHandler::AuthType auth_type) = 0;
201
202  // Get authentication type (for easier unlocking).
203  virtual ScreenlockBridge::LockHandler::AuthType GetAuthType(
204      const std::string& username) const = 0;
205
206 protected:
207  virtual ~SigninScreenHandlerDelegate() {}
208};
209
210// A class that handles the WebUI hooks in sign-in screen in OobeDisplay
211// and LoginDisplay.
212class SigninScreenHandler
213    : public BaseScreenHandler,
214      public LoginDisplayWebUIHandler,
215      public content::NotificationObserver,
216      public ScreenlockBridge::LockHandler,
217      public NetworkStateInformer::NetworkStateInformerObserver,
218      public input_method::ImeKeyboard::Observer,
219      public TouchViewControllerDelegate::Observer,
220      public OobeUI::Observer {
221 public:
222  SigninScreenHandler(
223      const scoped_refptr<NetworkStateInformer>& network_state_informer,
224      ErrorScreenActor* error_screen_actor,
225      CoreOobeActor* core_oobe_actor,
226      GaiaScreenHandler* gaia_screen_handler);
227  virtual ~SigninScreenHandler();
228
229  // Shows the sign in screen.
230  void Show(const LoginScreenContext& context);
231
232  // Shows the login spinner UI for retail mode logins.
233  void ShowRetailModeLoginSpinner();
234
235  // Sets delegate to be used by the handler. It is guaranteed that valid
236  // delegate is set before Show() method will be called.
237  void SetDelegate(SigninScreenHandlerDelegate* delegate);
238
239  void SetNativeWindowDelegate(NativeWindowDelegate* native_window_delegate);
240
241  // NetworkStateInformer::NetworkStateInformerObserver implementation:
242  virtual void OnNetworkReady() OVERRIDE;
243  virtual void UpdateState(ErrorScreenActor::ErrorReason reason) OVERRIDE;
244
245  // Required Local State preferences.
246  static void RegisterPrefs(PrefRegistrySimple* registry);
247
248  void set_kiosk_enable_flow_aborted_callback_for_test(
249      const base::Closure& callback) {
250    kiosk_enable_flow_aborted_callback_for_test_ = callback;
251  }
252
253  // OobeUI::Observer implemetation.
254  virtual void OnCurrentScreenChanged(OobeUI::Screen current_screen,
255                                      OobeUI::Screen new_screen) OVERRIDE;
256
257  // Returns least used user login input method.
258  std::string GetUserLRUInputMethod(const std::string& username) const;
259
260  void SetFocusPODCallbackForTesting(base::Closure callback);
261
262 private:
263  enum UIState {
264    UI_STATE_UNKNOWN = 0,
265    UI_STATE_GAIA_SIGNIN,
266    UI_STATE_ACCOUNT_PICKER,
267  };
268
269  friend class GaiaScreenHandler;
270  friend class ReportDnsCacheClearedOnUIThread;
271  friend class SupervisedUserCreationScreenHandler;
272
273  void ShowImpl();
274
275  // Updates current UI of the signin screen according to |ui_state|
276  // argument.  Optionally it can pass screen initialization data via
277  // |params| argument.
278  void UpdateUIState(UIState ui_state, base::DictionaryValue* params);
279
280  void UpdateStateInternal(ErrorScreenActor::ErrorReason reason,
281                           bool force_update);
282  void SetupAndShowOfflineMessage(NetworkStateInformer::State state,
283                                  ErrorScreenActor::ErrorReason reason);
284  void HideOfflineMessage(NetworkStateInformer::State state,
285                          ErrorScreenActor::ErrorReason reason);
286  void ReloadGaia(bool force_reload);
287
288  // BaseScreenHandler implementation:
289  virtual void DeclareLocalizedValues(LocalizedValuesBuilder* builder) OVERRIDE;
290  virtual void Initialize() OVERRIDE;
291  virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
292
293  // WebUIMessageHandler implementation:
294  virtual void RegisterMessages() OVERRIDE;
295
296  // LoginDisplayWebUIHandler implementation:
297  virtual void ClearAndEnablePassword() OVERRIDE;
298  virtual void ClearUserPodPassword() OVERRIDE;
299  virtual void OnUserRemoved(const std::string& username) OVERRIDE;
300  virtual void OnUserImageChanged(const user_manager::User& user) OVERRIDE;
301  virtual void OnPreferencesChanged() OVERRIDE;
302  virtual void ResetSigninScreenHandlerDelegate() OVERRIDE;
303  virtual void ShowError(int login_attempts,
304                         const std::string& error_text,
305                         const std::string& help_link_text,
306                         HelpAppLauncher::HelpTopic help_topic_id) OVERRIDE;
307  virtual void ShowGaiaPasswordChanged(const std::string& username) OVERRIDE;
308  virtual void ShowSigninUI(const std::string& email) OVERRIDE;
309  virtual void ShowPasswordChangedDialog(bool show_password_error) OVERRIDE;
310  virtual void ShowErrorScreen(LoginDisplay::SigninError error_id) OVERRIDE;
311  virtual void ShowSigninScreenForCreds(const std::string& username,
312                                        const std::string& password) OVERRIDE;
313  virtual void LoadUsers(const base::ListValue& users_list,
314                         bool show_guest) OVERRIDE;
315  virtual void SetPublicSessionDisplayName(
316      const std::string& user_id,
317      const std::string& display_name) OVERRIDE;
318  virtual void SetPublicSessionLocales(
319      const std::string& user_id,
320      scoped_ptr<base::ListValue> locales,
321      const std::string& default_locale,
322      bool multipleRecommendedLocales) OVERRIDE;
323
324  // content::NotificationObserver implementation:
325  virtual void Observe(int type,
326                       const content::NotificationSource& source,
327                       const content::NotificationDetails& details) OVERRIDE;
328
329  // ScreenlockBridge::LockHandler implementation:
330  virtual void ShowBannerMessage(const base::string16& message) OVERRIDE;
331  virtual void ShowUserPodCustomIcon(
332      const std::string& username,
333      const ScreenlockBridge::UserPodCustomIconOptions& icon) OVERRIDE;
334  virtual void HideUserPodCustomIcon(const std::string& username) OVERRIDE;
335  virtual void EnableInput() OVERRIDE;
336  virtual void SetAuthType(const std::string& username,
337                           ScreenlockBridge::LockHandler::AuthType auth_type,
338                           const base::string16& initial_value) OVERRIDE;
339  virtual ScreenlockBridge::LockHandler::AuthType GetAuthType(
340      const std::string& username) const OVERRIDE;
341  virtual void Unlock(const std::string& user_email) OVERRIDE;
342  virtual void AttemptEasySignin(const std::string& user_email,
343                                 const std::string& secret,
344                                 const std::string& key_label) OVERRIDE;
345
346  // TouchViewControllerDelegate::Observer implementation:
347  virtual void OnMaximizeModeStarted() OVERRIDE;
348  virtual void OnMaximizeModeEnded() OVERRIDE;
349
350  // Updates authentication extension. Called when device settings that affect
351  // sign-in (allow BWSI and allow whitelist) are changed.
352  void UserSettingsChanged();
353  void UpdateAddButtonStatus();
354
355  // Restore input focus to current user pod.
356  void RefocusCurrentPod();
357
358  // WebUI message handlers.
359  void HandleGetUsers();
360  void HandleAuthenticateUser(const std::string& username,
361                              const std::string& password);
362  void HandleAttemptUnlock(const std::string& username);
363  void HandleLaunchDemoUser();
364  void HandleLaunchIncognito();
365  void HandleLaunchPublicSession(const std::string& user_id,
366                                 const std::string& locale,
367                                 const std::string& input_method);
368  void HandleOfflineLogin(const base::ListValue* args);
369  void HandleShutdownSystem();
370  void HandleLoadWallpaper(const std::string& email);
371  void HandleRebootSystem();
372  void HandleRemoveUser(const std::string& email);
373  void HandleShowAddUser(const base::ListValue* args);
374  void HandleToggleEnrollmentScreen();
375  void HandleToggleKioskEnableScreen();
376  void HandleToggleResetScreen();
377  void HandleToggleKioskAutolaunchScreen();
378  void HandleCreateAccount();
379  void HandleAccountPickerReady();
380  void HandleWallpaperReady();
381  void HandleSignOutUser();
382  void HandleOpenProxySettings();
383  void HandleLoginVisible(const std::string& source);
384  void HandleCancelPasswordChangedFlow();
385  void HandleCancelUserAdding();
386  void HandleMigrateUserData(const std::string& password);
387  void HandleResyncUserData();
388  void HandleLoginUIStateChanged(const std::string& source, bool new_value);
389  void HandleUnlockOnLoginSuccess();
390  void HandleLoginScreenUpdate();
391  void HandleShowLoadingTimeoutError();
392  void HandleUpdateOfflineLogin(bool offline_login_active);
393  void HandleShowSupervisedUserCreationScreen();
394  void HandleFocusPod(const std::string& user_id);
395  void HandleHardlockPod(const std::string& user_id);
396  void HandleLaunchKioskApp(const std::string& app_id, bool diagnostic_mode);
397  void HandleRetrieveAuthenticatedUserEmail(double attempt_token);
398  void HandleGetPublicSessionKeyboardLayouts(const std::string& user_id,
399                                             const std::string& locale);
400  void HandleCancelConsumerManagementEnrollment();
401  void HandleGetTouchViewState();
402
403  // Sends the list of |keyboard_layouts| available for the |locale| that is
404  // currently selected for the public session identified by |user_id|.
405  void SendPublicSessionKeyboardLayouts(
406      const std::string& user_id,
407      const std::string& locale,
408      scoped_ptr<base::ListValue> keyboard_layouts);
409
410  // Returns true iff
411  // (i)   log in is restricted to some user list,
412  // (ii)  all users in the restricted list are present.
413  bool AllWhitelistedUsersPresent();
414
415  // Cancels password changed flow - switches back to login screen.
416  // Called as a callback after cookies are cleared.
417  void CancelPasswordChangedFlowInternal();
418
419  // Returns current visible screen.
420  OobeUI::Screen GetCurrentScreen() const;
421
422  // Returns true if current visible screen is the Gaia sign-in page.
423  bool IsGaiaVisible() const;
424
425  // Returns true if current visible screen is the error screen over
426  // Gaia sign-in page.
427  bool IsGaiaHiddenByError() const;
428
429  // Returns true if current screen is the error screen over signin
430  // screen.
431  bool IsSigninScreenHiddenByError() const;
432
433  // Returns true if guest signin is allowed.
434  bool IsGuestSigninAllowed() const;
435
436  // Returns true if offline login is allowed.
437  bool IsOfflineLoginAllowed() const;
438
439  bool ShouldLoadGaia() const;
440
441  // Update current input method (namely keyboard layout) in the given IME state
442  // to LRU by this user.
443  void SetUserInputMethod(const std::string& username,
444                          input_method::InputMethodManager::State* ime_state);
445
446  // Invoked when auto enrollment check progresses to decide whether to
447  // continue kiosk enable flow. Kiosk enable flow is resumed when
448  // |state| indicates that enrollment is not applicable.
449  void ContinueKioskEnableFlow(policy::AutoEnrollmentState state);
450
451  // Shows signin.
452  void OnShowAddUser();
453
454  GaiaScreenHandler::FrameState FrameState() const;
455  net::Error FrameError() const;
456
457  // input_method::ImeKeyboard::Observer implementation:
458  virtual void OnCapsLockChanged(bool enabled) OVERRIDE;
459
460  // Returns OobeUI object of NULL.
461  OobeUI* GetOobeUI() const;
462
463  // Gets the easy unlock service associated with the user. Can return NULL if
464  // user cannot be found, or there is not associated service.
465  EasyUnlockService* GetEasyUnlockServiceForUser(
466      const std::string& username) const;
467
468  // Current UI state of the signin screen.
469  UIState ui_state_;
470
471  // A delegate that glues this handler with backend LoginDisplay.
472  SigninScreenHandlerDelegate* delegate_;
473
474  // A delegate used to get gfx::NativeWindow.
475  NativeWindowDelegate* native_window_delegate_;
476
477  // Whether screen should be shown right after initialization.
478  bool show_on_init_;
479
480  // Keeps whether screen should be shown for OOBE.
481  bool oobe_ui_;
482
483  // Is account picker being shown for the first time.
484  bool is_account_picker_showing_first_time_;
485
486  // Network state informer used to keep signin screen up.
487  scoped_refptr<NetworkStateInformer> network_state_informer_;
488
489  // Set to true once |LOGIN_WEBUI_VISIBLE| notification is observed.
490  bool webui_visible_;
491  bool preferences_changed_delayed_;
492
493  ErrorScreenActor* error_screen_actor_;
494  CoreOobeActor* core_oobe_actor_;
495
496  bool is_first_update_state_call_;
497  bool offline_login_active_;
498  NetworkStateInformer::State last_network_state_;
499
500  base::CancelableClosure update_state_closure_;
501  base::CancelableClosure connecting_closure_;
502
503  content::NotificationRegistrar registrar_;
504
505  // Whether there is an auth UI pending. This flag is set on receiving
506  // NOTIFICATION_AUTH_NEEDED and reset on either NOTIFICATION_AUTH_SUPPLIED or
507  // NOTIFICATION_AUTH_CANCELLED.
508  bool has_pending_auth_ui_;
509
510  scoped_ptr<AutoEnrollmentController::ProgressCallbackList::Subscription>
511      auto_enrollment_progress_subscription_;
512
513  bool caps_lock_enabled_;
514
515  base::Closure kiosk_enable_flow_aborted_callback_for_test_;
516
517  // Non-owning ptr.
518  // TODO(ygorshenin@): remove this dependency.
519  GaiaScreenHandler* gaia_screen_handler_;
520
521  // Helper that retrieves the authenticated user's e-mail address.
522  scoped_ptr<AuthenticatedUserEmailRetriever> email_retriever_;
523
524  // Maximized mode controller delegate.
525  scoped_ptr<TouchViewControllerDelegate> max_mode_delegate_;
526
527  // Whether consumer management enrollment is in progress.
528  bool is_enrolling_consumer_management_;
529
530  // Input Method Engine state used at signin screen.
531  scoped_refptr<input_method::InputMethodManager::State> ime_state_;
532
533  // This callback captures "focusPod finished" event for tests.
534  base::Closure test_focus_pod_callback_;
535
536  // True if SigninScreenHandler has already been added to OobeUI observers.
537  bool oobe_ui_observer_added_;
538
539  base::WeakPtrFactory<SigninScreenHandler> weak_factory_;
540
541  DISALLOW_COPY_AND_ASSIGN(SigninScreenHandler);
542};
543
544}  // namespace chromeos
545
546#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_SIGNIN_SCREEN_HANDLER_H_
547