1 // Copyright (c) 2011 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_SCREEN_LOCKER_H_ 6 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_LOCKER_H_ 7 #pragma once 8 9 #include <string> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "base/task.h" 13 #include "base/time.h" 14 #include "chrome/browser/chromeos/login/captcha_view.h" 15 #include "chrome/browser/chromeos/login/login_status_consumer.h" 16 #include "chrome/browser/chromeos/login/message_bubble.h" 17 #include "chrome/browser/chromeos/login/user_manager.h" 18 #include "views/accelerator.h" 19 20 namespace gfx { 21 class Rect; 22 } // namespace gfx 23 24 namespace views { 25 class View; 26 class WidgetGtk; 27 } // namespace views 28 29 namespace chromeos { 30 31 class Authenticator; 32 class BackgroundView; 33 class InputEventObserver; 34 class LockerInputEventObserver; 35 class MessageBubble; 36 class MouseEventRelay; 37 class ScreenLockView; 38 class LoginFailure; 39 40 namespace test { 41 class ScreenLockerTester; 42 } // namespace test 43 44 // ScreenLocker creates a background view as well as ScreenLockView to 45 // authenticate the user. ScreenLocker manages its life cycle and will 46 // delete itself when it's unlocked. 47 class ScreenLocker : public LoginStatusConsumer, 48 public MessageBubbleDelegate, 49 public CaptchaView::Delegate, 50 public views::AcceleratorTarget { 51 public: 52 // Interface that helps switching from ScreenLockView to CaptchaView. 53 class ScreenLockViewContainer { 54 public: 55 virtual void SetScreenLockView(views::View* screen_lock_view) = 0; 56 57 protected: ~ScreenLockViewContainer()58 virtual ~ScreenLockViewContainer() {} 59 }; 60 61 explicit ScreenLocker(const UserManager::User& user); 62 63 // Returns the default instance if it has been created. default_screen_locker()64 static ScreenLocker* default_screen_locker() { 65 return screen_locker_; 66 } 67 68 // Initialize and show the screen locker. 69 void Init(); 70 71 // LoginStatusConsumer implements: 72 virtual void OnLoginFailure(const chromeos::LoginFailure& error); 73 virtual void OnLoginSuccess(const std::string& username, 74 const std::string& password, 75 const GaiaAuthConsumer::ClientLoginResult& result, 76 bool pending_requests); 77 78 // Overridden from views::BubbleDelegate. 79 virtual void BubbleClosing(Bubble* bubble, bool closed_by_escape); CloseOnEscape()80 virtual bool CloseOnEscape() { return true; } FadeInOnShow()81 virtual bool FadeInOnShow() { return false; } OnHelpLinkActivated()82 virtual void OnHelpLinkActivated() {} 83 84 // CaptchaView::Delegate implementation: 85 virtual void OnCaptchaEntered(const std::string& captcha); 86 87 // Authenticates the user with given |password| and authenticator. 88 void Authenticate(const string16& password); 89 90 // Close message bubble to clear error messages. 91 void ClearErrors(); 92 93 // (Re)enable input field. 94 void EnableInput(); 95 96 // Exit the chrome, which will sign out the current session. 97 void Signout(); 98 99 // Present user a CAPTCHA challenge with image from |captcha_url|, 100 // After that shows error bubble with |message|. 101 void ShowCaptchaAndErrorMessage(const GURL& captcha_url, 102 const std::wstring& message); 103 104 // Disables all UI needed and shows error bubble with |message|. 105 // If |sign_out_only| is true then all other input except "Sign Out" 106 // button is blocked. 107 void ShowErrorMessage(const std::wstring& message, bool sign_out_only); 108 109 // Called when the all inputs are grabbed. 110 void OnGrabInputs(); 111 112 // Returns the user to authenticate. user()113 const UserManager::User& user() const { 114 return user_; 115 } 116 117 // Returns a view that has given view |id|, or null if it doesn't exist. 118 views::View* GetViewByID(int id); 119 120 // Initialize ScreenLocker class. It will listen to 121 // LOGIN_USER_CHANGED notification so that the screen locker accepts 122 // lock event only after a user is logged in. 123 static void InitClass(); 124 125 // Show the screen locker. 126 static void Show(); 127 128 // Hide the screen locker. 129 static void Hide(); 130 131 // Notifies that PowerManager rejected UnlockScreen request. 132 static void UnlockScreenFailed(); 133 134 // Returns the tester 135 static test::ScreenLockerTester* GetTester(); 136 137 private: 138 friend class DeleteTask<ScreenLocker>; 139 friend class test::ScreenLockerTester; 140 friend class LockerInputEventObserver; 141 142 virtual ~ScreenLocker(); 143 144 // Sets the authenticator. 145 void SetAuthenticator(Authenticator* authenticator); 146 147 // Called when the screen lock is ready. 148 void ScreenLockReady(); 149 150 // Called when the window manager is ready to handle locked state. 151 void OnWindowManagerReady(); 152 153 // Shows error_info_ bubble with the |message| and |arrow_location| specified. 154 // Assumes that UI controls were locked before that. 155 void ShowErrorBubble(const std::wstring& message, 156 BubbleBorder::ArrowLocation arrow_location); 157 158 // Stops screen saver. 159 void StopScreenSaver(); 160 161 // Starts screen saver. 162 void StartScreenSaver(); 163 164 // Overridden from AcceleratorTarget: 165 virtual bool AcceleratorPressed(const views::Accelerator& accelerator); 166 167 // Event handler for client-event. 168 CHROMEGTK_CALLBACK_1(ScreenLocker, void, OnClientEvent, GdkEventClient*); 169 170 // The screen locker window. 171 views::WidgetGtk* lock_window_; 172 173 // TYPE_CHILD widget to grab the keyboard/mouse input. 174 views::WidgetGtk* lock_widget_; 175 176 // A view that accepts password. 177 ScreenLockView* screen_lock_view_; 178 179 // A view that can display html page as background. 180 BackgroundView* background_view_; 181 182 // View used to present CAPTCHA challenge input. 183 CaptchaView* captcha_view_; 184 185 // Containers that hold currently visible view. 186 // Initially it's ScreenLockView instance. 187 // When CAPTCHA input dialog is presented it's swapped to CaptchaView 188 // instance, then back after CAPTCHA input is done. 189 ScreenLockViewContainer* grab_container_; 190 ScreenLockViewContainer* background_container_; 191 192 // View that's not owned by grab_container_ - either ScreenLockView or 193 // CaptchaView instance. Keep that under scoped_ptr so that it's deleted. 194 scoped_ptr<views::View> secondary_view_; 195 196 // Postponed error message to be shown after CAPTCHA input is done. 197 std::wstring postponed_error_message_; 198 199 // Logged in user. 200 UserManager::User user_; 201 202 // Used to authenticate the user to unlock. 203 scoped_refptr<Authenticator> authenticator_; 204 205 // ScreenLocker grabs all keyboard and mouse events on its 206 // gdk window and never let other gdk_window to handle inputs. 207 // This MouseEventRelay object is used to forward events to 208 // the message bubble's gdk_window so that close button works. 209 scoped_ptr<MouseEventRelay> mouse_event_relay_; 210 211 // A message loop observer to detect user's keyboard/mouse event. 212 // Used when |unlock_on_input_| is true. 213 scoped_ptr<InputEventObserver> input_event_observer_; 214 215 // A message loop observer to detect user's keyboard/mouse event. 216 // Used when to show the screen locker upon such an event. 217 scoped_ptr<LockerInputEventObserver> locker_input_event_observer_; 218 219 // An info bubble to display login failure message. 220 MessageBubble* error_info_; 221 222 // True if the screen locker's window has been drawn. 223 bool drawn_; 224 225 // True if both mouse input and keyboard input are grabbed. 226 bool input_grabbed_; 227 228 // Unlock the screen when it detects key/mouse event without asking 229 // password. True when chrome is in BWSI or auto login mode. 230 bool unlock_on_input_; 231 232 // True if the screen is locked, or false otherwise. This changes 233 // from false to true, but will never change from true to 234 // false. Instead, ScreenLocker object gets deleted when unlocked. 235 bool locked_; 236 237 // Reference to the single instance of the screen locker object. 238 // This is used to make sure there is only one screen locker instance. 239 static ScreenLocker* screen_locker_; 240 241 // The time when the screen locker object is created. 242 base::Time start_time_; 243 // The time when the authentication is started. 244 base::Time authentication_start_time_; 245 246 DISALLOW_COPY_AND_ASSIGN(ScreenLocker); 247 }; 248 249 } // namespace chromeos 250 251 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_LOCKER_H_ 252