// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_LOCKER_H_
#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_LOCKER_H_
#pragma once
#include <string>
#include "base/memory/scoped_ptr.h"
#include "base/task.h"
#include "base/time.h"
#include "chrome/browser/chromeos/login/captcha_view.h"
#include "chrome/browser/chromeos/login/login_status_consumer.h"
#include "chrome/browser/chromeos/login/message_bubble.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "views/accelerator.h"
namespace gfx {
class Rect;
} // namespace gfx
namespace views {
class View;
class WidgetGtk;
} // namespace views
namespace chromeos {
class Authenticator;
class BackgroundView;
class InputEventObserver;
class LockerInputEventObserver;
class MessageBubble;
class MouseEventRelay;
class ScreenLockView;
class LoginFailure;
namespace test {
class ScreenLockerTester;
} // namespace test
// ScreenLocker creates a background view as well as ScreenLockView to
// authenticate the user. ScreenLocker manages its life cycle and will
// delete itself when it's unlocked.
class ScreenLocker : public LoginStatusConsumer,
public MessageBubbleDelegate,
public CaptchaView::Delegate,
public views::AcceleratorTarget {
public:
// Interface that helps switching from ScreenLockView to CaptchaView.
class ScreenLockViewContainer {
public:
virtual void SetScreenLockView(views::View* screen_lock_view) = 0;
protected:
virtual ~ScreenLockViewContainer() {}
};
explicit ScreenLocker(const UserManager::User& user);
// Returns the default instance if it has been created.
static ScreenLocker* default_screen_locker() {
return screen_locker_;
}
// Initialize and show the screen locker.
void Init();
// LoginStatusConsumer implements:
virtual void OnLoginFailure(const chromeos::LoginFailure& error);
virtual void OnLoginSuccess(const std::string& username,
const std::string& password,
const GaiaAuthConsumer::ClientLoginResult& result,
bool pending_requests);
// Overridden from views::BubbleDelegate.
virtual void BubbleClosing(Bubble* bubble, bool closed_by_escape);
virtual bool CloseOnEscape() { return true; }
virtual bool FadeInOnShow() { return false; }
virtual void OnHelpLinkActivated() {}
// CaptchaView::Delegate implementation:
virtual void OnCaptchaEntered(const std::string& captcha);
// Authenticates the user with given |password| and authenticator.
void Authenticate(const string16& password);
// Close message bubble to clear error messages.
void ClearErrors();
// (Re)enable input field.
void EnableInput();
// Exit the chrome, which will sign out the current session.
void Signout();
// Present user a CAPTCHA challenge with image from |captcha_url|,
// After that shows error bubble with |message|.
void ShowCaptchaAndErrorMessage(const GURL& captcha_url,
const std::wstring& message);
// Disables all UI needed and shows error bubble with |message|.
// If |sign_out_only| is true then all other input except "Sign Out"
// button is blocked.
void ShowErrorMessage(const std::wstring& message, bool sign_out_only);
// Called when the all inputs are grabbed.
void OnGrabInputs();
// Returns the user to authenticate.
const UserManager::User& user() const {
return user_;
}
// Returns a view that has given view |id|, or null if it doesn't exist.
views::View* GetViewByID(int id);
// Initialize ScreenLocker class. It will listen to
// LOGIN_USER_CHANGED notification so that the screen locker accepts
// lock event only after a user is logged in.
static void InitClass();
// Show the screen locker.
static void Show();
// Hide the screen locker.
static void Hide();
// Notifies that PowerManager rejected UnlockScreen request.
static void UnlockScreenFailed();
// Returns the tester
static test::ScreenLockerTester* GetTester();
private:
friend class DeleteTask<ScreenLocker>;
friend class test::ScreenLockerTester;
friend class LockerInputEventObserver;
virtual ~ScreenLocker();
// Sets the authenticator.
void SetAuthenticator(Authenticator* authenticator);
// Called when the screen lock is ready.
void ScreenLockReady();
// Called when the window manager is ready to handle locked state.
void OnWindowManagerReady();
// Shows error_info_ bubble with the |message| and |arrow_location| specified.
// Assumes that UI controls were locked before that.
void ShowErrorBubble(const std::wstring& message,
BubbleBorder::ArrowLocation arrow_location);
// Stops screen saver.
void StopScreenSaver();
// Starts screen saver.
void StartScreenSaver();
// Overridden from AcceleratorTarget:
virtual bool AcceleratorPressed(const views::Accelerator& accelerator);
// Event handler for client-event.
CHROMEGTK_CALLBACK_1(ScreenLocker, void, OnClientEvent, GdkEventClient*);
// The screen locker window.
views::WidgetGtk* lock_window_;
// TYPE_CHILD widget to grab the keyboard/mouse input.
views::WidgetGtk* lock_widget_;
// A view that accepts password.
ScreenLockView* screen_lock_view_;
// A view that can display html page as background.
BackgroundView* background_view_;
// View used to present CAPTCHA challenge input.
CaptchaView* captcha_view_;
// Containers that hold currently visible view.
// Initially it's ScreenLockView instance.
// When CAPTCHA input dialog is presented it's swapped to CaptchaView
// instance, then back after CAPTCHA input is done.
ScreenLockViewContainer* grab_container_;
ScreenLockViewContainer* background_container_;
// View that's not owned by grab_container_ - either ScreenLockView or
// CaptchaView instance. Keep that under scoped_ptr so that it's deleted.
scoped_ptr<views::View> secondary_view_;
// Postponed error message to be shown after CAPTCHA input is done.
std::wstring postponed_error_message_;
// Logged in user.
UserManager::User user_;
// Used to authenticate the user to unlock.
scoped_refptr<Authenticator> authenticator_;
// ScreenLocker grabs all keyboard and mouse events on its
// gdk window and never let other gdk_window to handle inputs.
// This MouseEventRelay object is used to forward events to
// the message bubble's gdk_window so that close button works.
scoped_ptr<MouseEventRelay> mouse_event_relay_;
// A message loop observer to detect user's keyboard/mouse event.
// Used when |unlock_on_input_| is true.
scoped_ptr<InputEventObserver> input_event_observer_;
// A message loop observer to detect user's keyboard/mouse event.
// Used when to show the screen locker upon such an event.
scoped_ptr<LockerInputEventObserver> locker_input_event_observer_;
// An info bubble to display login failure message.
MessageBubble* error_info_;
// True if the screen locker's window has been drawn.
bool drawn_;
// True if both mouse input and keyboard input are grabbed.
bool input_grabbed_;
// Unlock the screen when it detects key/mouse event without asking
// password. True when chrome is in BWSI or auto login mode.
bool unlock_on_input_;
// True if the screen is locked, or false otherwise. This changes
// from false to true, but will never change from true to
// false. Instead, ScreenLocker object gets deleted when unlocked.
bool locked_;
// Reference to the single instance of the screen locker object.
// This is used to make sure there is only one screen locker instance.
static ScreenLocker* screen_locker_;
// The time when the screen locker object is created.
base::Time start_time_;
// The time when the authentication is started.
base::Time authentication_start_time_;
DISALLOW_COPY_AND_ASSIGN(ScreenLocker);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_LOCKER_H_