1// Copyright 2014 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_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_IMPL_H_
6#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_IMPL_H_
7
8#include <string>
9#include <vector>
10
11#include "ash/shell_delegate.h"
12#include "base/compiler_specific.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/weak_ptr.h"
15#include "chrome/browser/chromeos/login/app_launch_controller.h"
16#include "chrome/browser/chromeos/login/auth/auth_prewarmer.h"
17#include "chrome/browser/chromeos/login/existing_user_controller.h"
18#include "chrome/browser/chromeos/login/ui/login_display.h"
19#include "chrome/browser/chromeos/login/ui/login_display_host.h"
20#include "chrome/browser/chromeos/login/wizard_controller.h"
21#include "chrome/browser/chromeos/settings/device_settings_service.h"
22#include "chromeos/audio/cras_audio_handler.h"
23#include "chromeos/dbus/session_manager_client.h"
24#include "content/public/browser/notification_observer.h"
25#include "content/public/browser/notification_registrar.h"
26#include "content/public/browser/web_contents_observer.h"
27#include "ui/gfx/display_observer.h"
28#include "ui/gfx/rect.h"
29#include "ui/keyboard/keyboard_controller_observer.h"
30#include "ui/views/widget/widget_removals_observer.h"
31
32class PrefService;
33
34namespace content {
35class RenderFrameHost;
36class WebContents;
37}
38
39namespace chromeos {
40
41class DemoAppLauncher;
42class FocusRingController;
43class KeyboardDrivenOobeKeyHandler;
44class OobeUI;
45class WebUILoginDisplay;
46class WebUILoginView;
47
48// An implementation class for OOBE/login WebUI screen host.
49// It encapsulates controllers, background integration and flow.
50class LoginDisplayHostImpl : public LoginDisplayHost,
51                             public content::NotificationObserver,
52                             public content::WebContentsObserver,
53                             public chromeos::SessionManagerClient::Observer,
54                             public chromeos::CrasAudioHandler::AudioObserver,
55                             public ash::VirtualKeyboardStateObserver,
56                             public keyboard::KeyboardControllerObserver,
57                             public gfx::DisplayObserver,
58                             public views::WidgetRemovalsObserver {
59 public:
60  explicit LoginDisplayHostImpl(const gfx::Rect& background_bounds);
61  virtual ~LoginDisplayHostImpl();
62
63  // Returns the default LoginDisplayHost instance if it has been created.
64  static LoginDisplayHost* default_host() {
65    return default_host_;
66  }
67
68  // LoginDisplayHost implementation:
69  virtual LoginDisplay* CreateLoginDisplay(
70      LoginDisplay::Delegate* delegate) OVERRIDE;
71  virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE;
72  virtual WebUILoginView* GetWebUILoginView() const OVERRIDE;
73  virtual void BeforeSessionStart() OVERRIDE;
74  virtual void Finalize() OVERRIDE;
75  virtual void OnCompleteLogin() OVERRIDE;
76  virtual void OpenProxySettings() OVERRIDE;
77  virtual void SetStatusAreaVisible(bool visible) OVERRIDE;
78  virtual AutoEnrollmentController* GetAutoEnrollmentController() OVERRIDE;
79  virtual void StartWizard(
80      const std::string& first_screen_name,
81      scoped_ptr<base::DictionaryValue> screen_parameters) OVERRIDE;
82  virtual WizardController* GetWizardController() OVERRIDE;
83  virtual AppLaunchController* GetAppLaunchController() OVERRIDE;
84  virtual void StartUserAdding(
85      const base::Closure& completion_callback) OVERRIDE;
86  virtual void StartSignInScreen(const LoginScreenContext& context) OVERRIDE;
87  virtual void ResumeSignInScreen() OVERRIDE;
88  virtual void OnPreferencesChanged() OVERRIDE;
89  virtual void PrewarmAuthentication() OVERRIDE;
90  virtual void StartAppLaunch(const std::string& app_id,
91                              bool diagnostic_mode) OVERRIDE;
92  virtual void StartDemoAppLaunch() OVERRIDE;
93
94  // Creates WizardController instance.
95  WizardController* CreateWizardController();
96
97  // Called when the first browser window is created, but before it's shown.
98  void OnBrowserCreated();
99
100  // Returns instance of the OOBE WebUI.
101  OobeUI* GetOobeUI() const;
102
103  const gfx::Rect& background_bounds() const { return background_bounds_; }
104
105  // Trace id for ShowLoginWebUI event (since there exists at most one login
106  // WebUI at a time).
107  static const int kShowLoginWebUIid;
108
109  views::Widget* login_window_for_test() { return login_window_; }
110
111 protected:
112  // content::NotificationObserver implementation:
113  virtual void Observe(int type,
114                       const content::NotificationSource& source,
115                       const content::NotificationDetails& details) OVERRIDE;
116
117  // Overridden from content::WebContentsObserver:
118  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
119
120  // Overridden from chromeos::SessionManagerClient::Observer:
121  virtual void EmitLoginPromptVisibleCalled() OVERRIDE;
122
123  // Overridden from chromeos::CrasAudioHandler::AudioObserver:
124  virtual void OnActiveOutputNodeChanged() OVERRIDE;
125
126  // Overridden from ash::KeyboardStateObserver:
127  virtual void OnVirtualKeyboardStateChanged(bool activated) OVERRIDE;
128
129  // Overridden from keyboard::KeyboardControllerObserver:
130  virtual void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) OVERRIDE;
131
132  // Overridden from gfx::DisplayObserver:
133  virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE;
134  virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE;
135  virtual void OnDisplayMetricsChanged(const gfx::Display& display,
136                                       uint32_t changed_metrics) OVERRIDE;
137
138  // Overriden from views::WidgetRemovalsObserver:
139  virtual void OnWillRemoveView(views::Widget* widget,
140                                views::View* view) OVERRIDE;
141
142 private:
143  // Way to restore if renderer have crashed.
144  enum RestorePath {
145    RESTORE_UNKNOWN,
146    RESTORE_WIZARD,
147    RESTORE_SIGN_IN,
148    RESTORE_ADD_USER_INTO_SESSION,
149  };
150
151  // Type of animations to run after the login screen.
152  enum FinalizeAnimationType {
153    ANIMATION_NONE,       // No animation.
154    ANIMATION_WORKSPACE,  // Use initial workspace animation (drop and
155                          // and fade in workspace). Used for user login.
156    ANIMATION_FADE_OUT,   // Fade out login screen. Used for app launch.
157  };
158
159  // Marks display host for deletion.
160  // If |post_quit_task| is true also posts Quit task to the MessageLoop.
161  void ShutdownDisplayHost(bool post_quit_task);
162
163  // Schedules workspace transition animation.
164  void ScheduleWorkspaceAnimation();
165
166  // Schedules fade out animation.
167  void ScheduleFadeOutAnimation();
168
169  // Progress callback registered with |auto_enrollment_controller_|.
170  void OnAutoEnrollmentProgress(policy::AutoEnrollmentState state);
171
172  // Loads given URL. Creates WebUILoginView if needed.
173  void LoadURL(const GURL& url);
174
175  // Shows OOBE/sign in WebUI that was previously initialized in hidden state.
176  void ShowWebUI();
177
178  // Starts postponed WebUI (OOBE/sign in) if it was waiting for
179  // wallpaper animation end.
180  void StartPostponedWebUI();
181
182  // Initializes |login_window_| and |login_view_| fields if needed.
183  void InitLoginWindowAndView();
184
185  // Closes |login_window_| and resets |login_window_| and |login_view_| fields.
186  void ResetLoginWindowAndView();
187
188  // Deletes |auth_prewarmer_|.
189  void OnAuthPrewarmDone();
190
191  // Toggles OOBE progress bar visibility, the bar is hidden by default.
192  void SetOobeProgressBarVisible(bool visible);
193
194  // Tries to play startup sound. If sound can't be played right now,
195  // for instance, because cras server is not initialized, playback
196  // will be delayed.
197  void TryToPlayStartupSound();
198
199  // Called when login-prompt-visible signal is caught.
200  void OnLoginPromptVisible();
201
202  // Used to calculate position of the screens and background.
203  gfx::Rect background_bounds_;
204
205  content::NotificationRegistrar registrar_;
206
207  base::WeakPtrFactory<LoginDisplayHostImpl> pointer_factory_;
208
209  // Default LoginDisplayHost.
210  static LoginDisplayHost* default_host_;
211
212  // The controller driving the auto-enrollment check.
213  scoped_ptr<AutoEnrollmentController> auto_enrollment_controller_;
214
215  // Subscription for progress callbacks from |auto_enrollement_controller_|.
216  scoped_ptr<AutoEnrollmentController::ProgressCallbackList::Subscription>
217      auto_enrollment_progress_subscription_;
218
219  // Sign in screen controller.
220  scoped_ptr<ExistingUserController> sign_in_controller_;
221
222  // OOBE and some screens (camera, recovery) controller.
223  scoped_ptr<WizardController> wizard_controller_;
224
225  // App launch controller.
226  scoped_ptr<AppLaunchController> app_launch_controller_;
227
228  // Demo app launcher.
229  scoped_ptr<DemoAppLauncher> demo_app_launcher_;
230
231  // Has ShutdownDisplayHost() already been called?  Used to avoid posting our
232  // own deletion to the message loop twice if the user logs out while we're
233  // still in the process of cleaning up after login (http://crbug.com/134463).
234  bool shutting_down_;
235
236  // Whether progress bar is shown on the OOBE page.
237  bool oobe_progress_bar_visible_;
238
239  // True if session start is in progress.
240  bool session_starting_;
241
242  // Container of the screen we are displaying.
243  views::Widget* login_window_;
244
245  // Container of the view we are displaying.
246  WebUILoginView* login_view_;
247
248  // Login display we are using.
249  WebUILoginDisplay* webui_login_display_;
250
251  // True if the login display is the current screen.
252  bool is_showing_login_;
253
254  // True if NOTIFICATION_WALLPAPER_ANIMATION_FINISHED notification has been
255  // received.
256  bool is_wallpaper_loaded_;
257
258  // Stores status area current visibility to be applied once login WebUI
259  // is shown.
260  bool status_area_saved_visibility_;
261
262  // If true, WebUI is initialized in a hidden state and shown after the
263  // wallpaper animation is finished (when it is enabled) or the user pods have
264  // been loaded (otherwise).
265  // By default is true. Could be used to tune performance if needed.
266  bool initialize_webui_hidden_;
267
268  // True if WebUI is initialized in hidden state and we're waiting for
269  // wallpaper load animation to finish.
270  bool waiting_for_wallpaper_load_;
271
272  // True if WebUI is initialized in hidden state and we're waiting for user
273  // pods to load.
274  bool waiting_for_user_pods_;
275
276  // How many times renderer has crashed.
277  int crash_count_;
278
279  // Way to restore if renderer have crashed.
280  RestorePath restore_path_;
281
282  // Stored parameters for StartWizard, required to restore in case of crash.
283  std::string wizard_first_screen_name_;
284  scoped_ptr<base::DictionaryValue> wizard_screen_parameters_;
285
286  // Called before host deletion.
287  base::Closure completion_callback_;
288
289  // Active instance of authentication prewarmer.
290  scoped_ptr<AuthPrewarmer> auth_prewarmer_;
291
292  // A focus ring controller to draw focus ring around view for keyboard
293  // driven oobe.
294  scoped_ptr<FocusRingController> focus_ring_controller_;
295
296  // Handles special keys for keyboard driven oobe.
297  scoped_ptr<KeyboardDrivenOobeKeyHandler> keyboard_driven_oobe_key_handler_;
298
299  FinalizeAnimationType finalize_animation_type_;
300
301  // Time when login prompt visible signal is received. Used for
302  // calculations of delay before startup sound.
303  base::TimeTicks login_prompt_visible_time_;
304
305  // True when request to play startup sound was sent to
306  // SoundsManager.
307  bool startup_sound_played_;
308
309  // When true, startup sound should be played only when spoken
310  // feedback is enabled.  Otherwise, startup sound should be played
311  // in any case.
312  bool startup_sound_honors_spoken_feedback_;
313
314  // True is subscribed as keyboard controller observer.
315  bool is_observing_keyboard_;
316
317  // The bounds of the virtual keyboard.
318  gfx::Rect keyboard_bounds_;
319
320#if defined(USE_ATHENA)
321  scoped_ptr<aura::Window> login_screen_container_;
322#endif
323
324  base::WeakPtrFactory<LoginDisplayHostImpl> animation_weak_ptr_factory_;
325
326  DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostImpl);
327};
328
329}  // namespace chromeos
330
331#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_IMPL_H_
332