summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-08 02:51:42 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-08 02:51:42 +0000
commit93c7843a5f99fe5e0d9665d58f1ba1deaba131ba (patch)
tree147ba83f7c0d01ba4b93f1e5e04fb09ea3c58588
parent8ddfe30967dde6a7297d691c0e72ad8e7b9114e7 (diff)
downloadchromium_src-93c7843a5f99fe5e0d9665d58f1ba1deaba131ba.zip
chromium_src-93c7843a5f99fe5e0d9665d58f1ba1deaba131ba.tar.gz
chromium_src-93c7843a5f99fe5e0d9665d58f1ba1deaba131ba.tar.bz2
* Show error message when unlocking failed.
* Add "sign out" button * Let chrome crash when grab is borken. * send ScreenIsLocked signal after all inputs are grabbed. BUG=chromium-os:2914,chromium-os:2614 TEST=manual: set the content of /var/lib/power_manager/use_xscreensaver to 1, reboot the machine and login hit ctr-alt-l to enter screenlock mode 1) typing in wrong password should show message bubble with error message 2) pressing "Sign out" will terminate the session and move to login screen Review URL: http://codereview.chromium.org/2685006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49141 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/chromeos/login/screen_lock_view.cc103
-rw-r--r--chrome/browser/chromeos/login/screen_lock_view.h9
-rw-r--r--chrome/browser/chromeos/login/screen_locker.cc186
-rw-r--r--chrome/browser/chromeos/login/screen_locker.h32
5 files changed, 313 insertions, 23 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 33b2bcc..c39ae8dc 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7470,6 +7470,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_LOGIN_BUTTON">
Sign in
</message>
+ <message name="IDS_SCREEN_LOCK_ACTIVE_USER">
+ Active user
+ </message>
+ <message name="IDS_SCREEN_LOCK_SIGN_OUT">
+ Sign out
+ </message>
<message name="IDS_CREATE_ACCOUNT_BUTTON">
Create a Google Account now
</message>
diff --git a/chrome/browser/chromeos/login/screen_lock_view.cc b/chrome/browser/chromeos/login/screen_lock_view.cc
index 1aa7bca..2c59cf0 100644
--- a/chrome/browser/chromeos/login/screen_lock_view.cc
+++ b/chrome/browser/chromeos/login/screen_lock_view.cc
@@ -12,17 +12,21 @@
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
+#include "views/background.h"
#include "views/controls/image_view.h"
#include "views/controls/label.h"
#include "views/grid_layout.h"
namespace {
+// TODO(oshima): Refactor this and UserContoller and use the
+// same codebase to show the user's image.
+
// Max image size.
const int kMaxImageSize = 260;
// Gap between edge and image view, and image view and controls.
-const int kBorderSize = 30;
+const int kBorderSize = 5;
// Background color.
const SkColor kBackgroundColor = SK_ColorWHITE;
@@ -30,14 +34,81 @@ const SkColor kBackgroundColor = SK_ColorWHITE;
// Text color.
const SkColor kTextColor = SK_ColorWHITE;
+// Background color of the login status area.
+const SkColor kSignoutBackgroundColor = 0xFF007700;
+
+// Left margin to the "Active User" text.
+const int kSignoutLeftOffset = 10;
+
+// Command tag for buttons on the lock screen.
+enum Command {
+ UNLOCK,
+ SIGN_OUT,
+};
+
} // namespace
namespace chromeos {
using views::GridLayout;
+// The view that shows the Sign out button below the user's image.
+class SignoutView : public views::View {
+ public:
+ explicit SignoutView(chromeos::ScreenLockView* lock_view) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ const gfx::Font& font = rb.GetFont(ResourceBundle::SmallFont);
+
+ active_user_label_ = new views::Label(
+ l10n_util::GetString(IDS_SCREEN_LOCK_ACTIVE_USER));
+ active_user_label_->SetFont(font);
+ active_user_label_->SetColor(kTextColor);
+
+ signout_button_ = new views::TextButton(
+ lock_view, l10n_util::GetString(IDS_SCREEN_LOCK_SIGN_OUT));
+ signout_button_->SetFont(font);
+ signout_button_->SetEnabledColor(kTextColor);
+ signout_button_->SetNormalHasBorder(false);
+ signout_button_->set_tag(SIGN_OUT);
+
+ AddChildView(active_user_label_);
+ AddChildView(signout_button_);
+
+ set_background(views::Background::CreateSolidBackground(
+ kSignoutBackgroundColor));
+ }
+
+ // views::View overrides.
+ virtual void Layout() {
+ gfx::Size label = active_user_label_->GetPreferredSize();
+ gfx::Size button = signout_button_->GetPreferredSize();
+ active_user_label_->SetBounds(kSignoutLeftOffset,
+ (height() - label.height()) / 2,
+ label.width(), label.height());
+ signout_button_->SetBounds(
+ width() - button.width(), (height() - button.height()) / 2,
+ button.width(), button.height());
+ }
+
+ virtual gfx::Size GetPreferredSize() {
+ gfx::Size label = active_user_label_->GetPreferredSize();
+ gfx::Size button = signout_button_->GetPreferredSize();
+ return gfx::Size(label.width() + button.width(),
+ std::max(label.height(), button.height()));
+ }
+
+ private:
+ friend class ScreenLockView;
+
+ views::Label* active_user_label_;
+ views::TextButton* signout_button_;
+
+ DISALLOW_COPY_AND_ASSIGN(SignoutView);
+};
+
ScreenLockView::ScreenLockView(ScreenLocker* screen_locker)
- : image_view_(NULL),
+ : signout_view_(NULL),
+ image_view_(NULL),
password_field_(NULL),
unlock_button_(NULL),
screen_locker_(screen_locker) {
@@ -53,6 +124,8 @@ void ScreenLockView::Init() {
main->set_background(
views::Background::CreateSolidBackground(kBackgroundColor));
+ signout_view_ = new SignoutView(this);
+
// Password field.
password_field_ = new views::Textfield(views::Textfield::STYLE_PASSWORD);
password_field_->set_text_to_display_when_empty(
@@ -63,6 +136,7 @@ void ScreenLockView::Init() {
// TODO(sky|oshima): change ids
unlock_button_ = new views::TextButton(
this, l10n_util::GetString(IDS_LOGIN_BUTTON));
+ unlock_button_->set_tag(UNLOCK);
// User icon.
image_view_ = new views::ImageView();
@@ -99,6 +173,8 @@ void ScreenLockView::Init() {
layout->AddPaddingRow(0, kBorderSize);
layout->StartRow(0, 0);
layout->AddView(image_view_);
+ layout->StartRow(0, 0);
+ layout->AddView(signout_view_);
layout->AddPaddingRow(0, kBorderSize);
layout->StartRow(0, 1);
layout->AddView(password_field_);
@@ -129,6 +205,16 @@ void ScreenLockView::ClearAndSetFocusToPassword() {
password_field_->SetText(string16());
}
+void ScreenLockView::SetSignoutEnabled(bool enabled) {
+ signout_view_->signout_button_->SetEnabled(enabled);
+}
+
+gfx::Rect ScreenLockView::GetPasswordBoundsRelativeTo(const views::View* view) {
+ gfx::Point p;
+ views::View::ConvertPointToView(password_field_, view, &p);
+ return gfx::Rect(p, size());
+}
+
void ScreenLockView::SetEnabled(bool enabled) {
views::View::SetEnabled(enabled);
@@ -143,12 +229,22 @@ void ScreenLockView::SetEnabled(bool enabled) {
void ScreenLockView::ButtonPressed(views::Button* sender,
const views::Event& event) {
- screen_locker_->Authenticate(password_field_->text());
+ switch (sender->tag()) {
+ case UNLOCK:
+ screen_locker_->Authenticate(password_field_->text());
+ break;
+ case SIGN_OUT:
+ screen_locker_->Signout();
+ break;
+ default:
+ NOTREACHED();
+ }
}
bool ScreenLockView::HandleKeystroke(
views::Textfield* sender,
const views::Textfield::Keystroke& keystroke) {
+ screen_locker_->ClearErrors();
if (keystroke.GetKeyboardCode() == base::VKEY_RETURN) {
screen_locker_->Authenticate(password_field_->text());
return true;
@@ -183,4 +279,3 @@ void ScreenLockView::SetImage(const SkBitmap& image,
}
} // namespace chromeos
-
diff --git a/chrome/browser/chromeos/login/screen_lock_view.h b/chrome/browser/chromeos/login/screen_lock_view.h
index 49de5a2..c496390 100644
--- a/chrome/browser/chromeos/login/screen_lock_view.h
+++ b/chrome/browser/chromeos/login/screen_lock_view.h
@@ -18,6 +18,7 @@ class ImageView;
namespace chromeos {
class ScreenLocker;
+class SignoutView;
namespace test {
class ScreenLockerTester;
@@ -38,6 +39,12 @@ class ScreenLockView : public views::View,
// Clears and sets the focus to the password field.
void ClearAndSetFocusToPassword();
+ // Enable/Disable signout button.
+ void SetSignoutEnabled(bool enabled);
+
+ // Returns the bounds of the password field in ScreenLocker's coordinate.
+ gfx::Rect GetPasswordBoundsRelativeTo(const views::View* view);
+
// views::View implementation:
virtual void SetEnabled(bool enabled);
@@ -63,6 +70,8 @@ class ScreenLockView : public views::View,
int desired_width,
int desired_height);
+ SignoutView* signout_view_;
+
// For editing the password.
views::ImageView* image_view_;
views::Textfield* password_field_;
diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc
index 60540c7..bba8f61 100644
--- a/chrome/browser/chromeos/login/screen_locker.cc
+++ b/chrome/browser/chromeos/login/screen_locker.cc
@@ -6,23 +6,33 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "base/message_loop.h"
#include "base/singleton.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_list.h"
#include "chrome/browser/chromeos/cros/screen_lock_library.h"
#include "chrome/browser/chromeos/login/authenticator.h"
#include "chrome/browser/chromeos/login/background_view.h"
#include "chrome/browser/chromeos/login/login_utils.h"
+#include "chrome/browser/chromeos/login/message_bubble.h"
#include "chrome/browser/chromeos/login/screen_lock_view.h"
+#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/common/notification_service.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
#include "views/screen.h"
+#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"
+#include "chrome/browser/chromeos/wm_ipc.h"
+#include "third_party/cros/chromeos_wm_ipc_enums.h"
+
namespace {
// The maxium times that the screen locker should try to grab input,
// and its interval. It has to be able to grab all inputs in 30 seconds,
// otherwise chromium process fails and the session is terminated.
-const int64 kRetryGrabIntervalMs = 1000;
-const int kGrabFailureLimit = 30;
+const int64 kRetryGrabIntervalMs = 500;
+const int kGrabFailureLimit = 60;
// Observer to start ScreenLocker when the screen lock
class ScreenLockObserver : public chromeos::ScreenLockLibrary::Observer,
@@ -63,19 +73,13 @@ class ScreenLockObserver : public chromeos::ScreenLockLibrary::Observer,
DISALLOW_COPY_AND_ASSIGN(ScreenLockObserver);
};
-} // namespace
-
-namespace chromeos {
-
-// static
-ScreenLocker* ScreenLocker::screen_locker_ = NULL;
-
// A child widget that grabs both keyboard and pointer input.
// TODO(oshima): catch grab-broke event and quit if it ever happenes.
class GrabWidget : public views::WidgetGtk {
public:
- GrabWidget()
+ explicit GrabWidget(chromeos::ScreenLocker* screen_locker)
: views::WidgetGtk(views::WidgetGtk::TYPE_CHILD),
+ screen_locker_(screen_locker),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
grab_failure_count_(0),
kbd_grab_status_(GDK_GRAB_INVALID_TIME),
@@ -88,17 +92,34 @@ class GrabWidget : public views::WidgetGtk {
if (current_grab_window)
gtk_grab_remove(current_grab_window);
- DoGrab();
+ gtk_grab_add(window_contents());
// Now steal all inputs.
TryGrabAllInputs();
}
+ virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event) {
+ WidgetGtk::OnButtonPress(widget, event);
+ // Never propagate event to parent.
+ return true;
+ }
+
// Try to grab all inputs. It initiates another try if it fails to
// grab and the retry count is within a limit, or fails with CHECK.
void TryGrabAllInputs();
private:
+ virtual void HandleGrabBroke() {
+ // Input should never be stolen from ScreenLocker once it's
+ // grabbed. If this happens, it's a bug and has to be fixed. We
+ // let chrome crash to get a crash report and dump, and
+ // SessionManager will terminate the session to logout.
+ CHECK(kbd_grab_status_ != GDK_GRAB_SUCCESS ||
+ kbd_grab_status_ != GDK_GRAB_SUCCESS)
+ << "Grab Broke. quitting";
+ }
+
+ chromeos::ScreenLocker* screen_locker_;
ScopedRunnableMethodFactory<GrabWidget> task_factory_;
// The number times the widget tried to grab all focus.
@@ -140,6 +161,8 @@ void GrabWidget::TryGrabAllInputs() {
<< "Failed to grab keyboard input:" << kbd_grab_status_;
CHECK_EQ(GDK_GRAB_SUCCESS, mouse_grab_status_)
<< "Failed to grab pointer input:" << mouse_grab_status_;
+ DLOG(INFO) << "Grab Success";
+ screen_locker_->ScreenLockReady();
}
}
@@ -147,16 +170,79 @@ void GrabWidget::TryGrabAllInputs() {
namespace chromeos {
+// static
+ScreenLocker* ScreenLocker::screen_locker_ = NULL;
+
+// A event observer that forwards gtk events from one window to another.
+// See screen_locker.h for more details.
+class MouseEventRelay : public MessageLoopForUI::Observer {
+ public:
+ MouseEventRelay(GdkWindow* src, GdkWindow* dest) : src_(src), dest_(dest) {
+ DCHECK(src_);
+ DCHECK(dest_);
+ gint src_x, src_y, dest_x, dest_y, width, height, depth;
+ gdk_window_get_geometry(src_, &src_x, &src_y, &width, &height, &depth);
+ gdk_window_get_geometry(dest_, &dest_x, &dest_y, &width, &height, &depth);
+
+ offset_.SetPoint(dest_x - src_x, dest_y - src_y);
+ }
+
+ virtual void WillProcessEvent(GdkEvent* event) {}
+
+ virtual void DidProcessEvent(GdkEvent* event) {
+ if (event->any.window != src_) {
+ DLOG(INFO) << "ignore event src non grab window: " << event->type;
+ return;
+ }
+
+ if (event->type == GDK_BUTTON_PRESS ||
+ event->type == GDK_BUTTON_RELEASE) {
+ GdkEvent* copy = gdk_event_copy(event);
+ copy->button.window = dest_;
+ g_object_ref(copy->button.window);
+ copy->button.x -= offset_.x();
+ copy->button.y -= offset_.y();
+
+ gdk_event_put(copy);
+ gdk_event_free(copy);
+ } else if (event->type == GDK_MOTION_NOTIFY) {
+ GdkEvent* copy = gdk_event_copy(event);
+ copy->button.window = dest_;
+ g_object_ref(copy->button.window);
+ copy->motion.x -= offset_.x();
+ copy->motion.y -= offset_.y();
+
+ gdk_event_put(copy);
+ gdk_event_free(copy);
+ }
+ }
+
+ private:
+ GdkWindow* src_;
+ GdkWindow* dest_;
+
+ // Offset from src_'s origin to dest_'s origin.
+ gfx::Point offset_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseEventRelay);
+};
+
+} // namespace chromeos
+
+namespace chromeos {
+
ScreenLocker::ScreenLocker(const UserManager::User& user)
: lock_window_(NULL),
lock_widget_(NULL),
screen_lock_view_(NULL),
- user_(user) {
+ user_(user),
+ error_info_(NULL) {
DCHECK(!screen_locker_);
screen_locker_ = this;
}
ScreenLocker::~ScreenLocker() {
+ ClearErrors();
DCHECK(lock_window_);
lock_window_->Close();
// lock_widget_ will be deleted by gtk's destroy signal.
@@ -170,6 +256,11 @@ void ScreenLocker::Init(const gfx::Rect& bounds) {
views::View* screen = new BackgroundView();
lock_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
lock_window_->Init(NULL, bounds);
+ DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView()));
+ WmIpc::instance()->SetWindowType(
+ lock_window_->GetNativeView(),
+ WM_IPC_WINDOW_CHROME_SCREEN_LOCKER,
+ NULL);
lock_window_->SetContentsView(screen);
lock_window_->Show();
@@ -179,7 +270,7 @@ void ScreenLocker::Init(const gfx::Rect& bounds) {
gfx::Size size = screen_lock_view_->GetPreferredSize();
- lock_widget_ = new GrabWidget();
+ lock_widget_ = new GrabWidget(this);
lock_widget_->MakeTransparent();
lock_widget_->InitWithWidget(lock_window_,
gfx::Rect((bounds.width() - size.width()) / 2,
@@ -187,8 +278,8 @@ void ScreenLocker::Init(const gfx::Rect& bounds) {
size.width(),
size.height()));
lock_widget_->SetContentsView(screen_lock_view_);
+ lock_widget_->GetRootView()->SetVisible(false);
lock_widget_->Show();
- screen_lock_view_->ClearAndSetFocusToPassword();
}
void ScreenLocker::SetAuthenticator(Authenticator* authenticator) {
@@ -198,6 +289,34 @@ void ScreenLocker::SetAuthenticator(Authenticator* authenticator) {
void ScreenLocker::OnLoginFailure(const std::string& error) {
DLOG(INFO) << "OnLoginFailure";
EnableInput();
+ // Don't enable signout button here as we're showing
+ // MessageBubble.
+ gfx::Rect rect = screen_lock_view_->GetPasswordBoundsRelativeTo(
+ lock_widget_->GetRootView());
+ gfx::Rect lock_widget_bounds;
+ lock_widget_->GetBounds(&lock_widget_bounds, false);
+ rect.Offset(lock_widget_bounds.x(), lock_widget_bounds.y());
+
+ if (error_info_)
+ error_info_->Close();
+ std::wstring msg = l10n_util::GetString(IDS_LOGIN_ERROR_AUTHENTICATING);
+ if (!error.empty())
+ msg += L"\n" + ASCIIToWide(error);
+
+ error_info_ = MessageBubble::ShowNoGrab(
+ lock_window_,
+ rect,
+ BubbleBorder::BOTTOM_LEFT,
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
+ msg,
+ this);
+ if (mouse_event_relay_.get()) {
+ MessageLoopForUI::current()->RemoveObserver(mouse_event_relay_.get());
+ }
+ mouse_event_relay_.reset(
+ new MouseEventRelay(lock_widget_->GetNativeView()->window,
+ error_info_->GetNativeView()->window));
+ MessageLoopForUI::current()->AddObserver(mouse_event_relay_.get());
}
void ScreenLocker::OnLoginSuccess(const std::string& username,
@@ -208,8 +327,19 @@ void ScreenLocker::OnLoginSuccess(const std::string& username,
CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenUnlockRequested();
}
+void ScreenLocker::InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape) {
+ error_info_ = NULL;
+ screen_lock_view_->SetSignoutEnabled(true);
+ if (mouse_event_relay_.get()) {
+ MessageLoopForUI::current()->RemoveObserver(mouse_event_relay_.get());
+ mouse_event_relay_.reset();
+ }
+}
+
void ScreenLocker::Authenticate(const string16& password) {
screen_lock_view_->SetEnabled(false);
+ screen_lock_view_->SetSignoutEnabled(false);
ChromeThread::PostTask(
ChromeThread::FILE, FROM_HERE,
NewRunnableMethod(authenticator_.get(),
@@ -218,11 +348,36 @@ void ScreenLocker::Authenticate(const string16& password) {
UTF16ToUTF8(password)));
}
+void ScreenLocker::ClearErrors() {
+ if (error_info_) {
+ error_info_->Close();
+ error_info_ = NULL;
+ }
+}
+
void ScreenLocker::EnableInput() {
screen_lock_view_->SetEnabled(true);
screen_lock_view_->ClearAndSetFocusToPassword();
}
+void ScreenLocker::Signout() {
+ if (!error_info_) {
+ // TODO(oshima): record this action in user metrics.
+ BrowserList::CloseAllBrowsersAndExit();
+
+ // Don't hide yet the locker because the chrome screen may become visible
+ // briefly.
+ }
+}
+
+void ScreenLocker::ScreenLockReady() {
+ // Don't show the password field until we grab all inputs.
+ lock_widget_->GetRootView()->SetVisible(true);
+ EnableInput();
+ if (CrosLibrary::Get()->EnsureLoaded())
+ CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenLockCompleted();
+}
+
// static
void ScreenLocker::Show() {
DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
@@ -236,9 +391,6 @@ void ScreenLocker::Show() {
new ScreenLocker(UserManager::Get()->logged_in_user());
locker->Init(bounds);
}
- // TODO(oshima): Wait for a message from WM to complete the process.
- if (CrosLibrary::Get()->EnsureLoaded())
- CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenLockCompleted();
}
// static
diff --git a/chrome/browser/chromeos/login/screen_locker.h b/chrome/browser/chromeos/login/screen_locker.h
index 2a2a81d..9d0a894 100644
--- a/chrome/browser/chromeos/login/screen_locker.h
+++ b/chrome/browser/chromeos/login/screen_locker.h
@@ -10,6 +10,7 @@
#include "base/task.h"
#include "chrome/browser/chromeos/login/login_status_consumer.h"
#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/views/info_bubble.h"
namespace gfx {
class Rect;
@@ -22,6 +23,8 @@ class WidgetGtk;
namespace chromeos {
class Authenticator;
+class MessageBubble;
+class MouseEventRelay;
class ScreenLockView;
namespace test {
@@ -31,7 +34,8 @@ class ScreenLockerTester;
// 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 {
+class ScreenLocker : public LoginStatusConsumer,
+ public InfoBubbleDelegate {
public:
explicit ScreenLocker(const UserManager::User& user);
@@ -43,12 +47,27 @@ class ScreenLocker : public LoginStatusConsumer {
virtual void OnLoginSuccess(const std::string& username,
const std::string& credentials);
+ // Overridden from views::InfoBubbleDelegate.
+ virtual void InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape);
+ virtual bool CloseOnEscape() { return true; }
+ virtual bool FadeInOnShow() { return false; }
+
// 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();
+
+ // Called when the screen locker is ready.
+ void ScreenLockReady();
+
// Returns the user to authenticate.
const UserManager::User& user() const {
return user_;
@@ -92,9 +111,18 @@ class ScreenLocker : public LoginStatusConsumer {
// Logged in user.
UserManager::User user_;
- // Used for logging in.
+ // 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_;
+
+ // An info bubble to display login failure message.
+ MessageBubble* error_info_;
+
// 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_;