Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(360)

Unified Diff: chrome/browser/chromeos/login/screen_locker.cc

Issue 2458002: Initialize screen locker before letting user logged in. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: fix login_browsertest Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/login/login_browsertest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/login/screen_locker.cc
diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc
index 23b4a76fc2143a2afbf67811f0581f831c656828..507f0fe3ffcdbe6d0b513da9bb77649e9d91dc12 100644
--- a/chrome/browser/chromeos/login/screen_locker.cc
+++ b/chrome/browser/chromeos/login/screen_locker.cc
@@ -18,6 +18,11 @@
#include "views/widget/widget_gtk.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;
// Observer to start ScreenLocker when the screen lock
class ScreenLockObserver : public chromeos::ScreenLockLibrary::Observer,
@@ -69,7 +74,12 @@ ScreenLocker* ScreenLocker::screen_locker_ = NULL;
// TODO(oshima): catch grab-broke event and quit if it ever happenes.
class GrabWidget : public views::WidgetGtk {
public:
- GrabWidget() : views::WidgetGtk(views::WidgetGtk::TYPE_CHILD) {
+ GrabWidget()
+ : views::WidgetGtk(views::WidgetGtk::TYPE_CHILD),
+ ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
+ grab_failure_count_(0),
+ kbd_grab_status_(GDK_GRAB_INVALID_TIME),
+ mouse_grab_status_(GDK_GRAB_INVALID_TIME) {
}
virtual void Show() {
@@ -79,11 +89,34 @@ class GrabWidget : public views::WidgetGtk {
gtk_grab_remove(current_grab_window);
DoGrab();
- GdkGrabStatus kbd_status =
- gdk_keyboard_grab(window_contents()->window, FALSE,
- GDK_CURRENT_TIME);
- CHECK_EQ(GDK_GRAB_SUCCESS, kbd_status) << "Failed to grab keyboard input";
- GdkGrabStatus ptr_status =
+
+ // Now steal all inputs.
+ TryGrabAllInputs();
+ }
+
+ // 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:
+ ScopedRunnableMethodFactory<GrabWidget> task_factory_;
+
+ // The number times the widget tried to grab all focus.
+ int grab_failure_count_;
+ // Status of keyboard and mouse grab.
+ GdkGrabStatus kbd_grab_status_;
+ GdkGrabStatus mouse_grab_status_;
+
+ DISALLOW_COPY_AND_ASSIGN(GrabWidget);
+};
+
+
+void GrabWidget::TryGrabAllInputs() {
+ if (kbd_grab_status_ != GDK_GRAB_SUCCESS)
+ kbd_grab_status_ = gdk_keyboard_grab(window_contents()->window, FALSE,
+ GDK_CURRENT_TIME);
+ if (mouse_grab_status_ != GDK_GRAB_SUCCESS) {
+ mouse_grab_status_ =
gdk_pointer_grab(window_contents()->window,
FALSE,
static_cast<GdkEventMask>(
@@ -92,12 +125,23 @@ class GrabWidget : public views::WidgetGtk {
NULL,
NULL,
GDK_CURRENT_TIME);
- CHECK_EQ(GDK_GRAB_SUCCESS, ptr_status) << "Failed to grab pointer input";
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GrabWidget);
-};
+ if ((kbd_grab_status_ != GDK_GRAB_SUCCESS ||
+ kbd_grab_status_ != GDK_GRAB_SUCCESS) &&
+ grab_failure_count_++ < kGrabFailureLimit) {
+ DLOG(WARNING) << "Failed to grab inputs. Trying again in 1 second: kbd="
+ << kbd_grab_status_ << ", mouse=" << mouse_grab_status_;
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ task_factory_.NewRunnableMethod(&GrabWidget::TryGrabAllInputs),
+ kRetryGrabIntervalMs);
+ } else {
+ CHECK_EQ(GDK_GRAB_SUCCESS, kbd_grab_status_)
+ << "Failed to grab keyboard input:" << kbd_grab_status_;
+ CHECK_EQ(GDK_GRAB_SUCCESS, mouse_grab_status_)
+ << "Failed to grab pointer input:" << mouse_grab_status_;
+ }
+}
} // namespace
@@ -182,11 +226,16 @@ void ScreenLocker::EnableInput() {
// static
void ScreenLocker::Show() {
DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
- DCHECK(!screen_locker_);
- gfx::Rect bounds(views::Screen::GetMonitorWorkAreaNearestWindow(NULL));
- ScreenLocker* locker =
- new ScreenLocker(UserManager::Get()->logged_in_user());
- locker->Init(bounds);
+ // TODO(oshima): Currently, PowerManager may send a lock screen event
+ // even if a screen is locked. Investigate & solve the issue and
+ // enable this again if it's possible.
+ // DCHECK(!screen_locker_);
+ if (!screen_locker_) {
+ gfx::Rect bounds(views::Screen::GetMonitorWorkAreaNearestWindow(NULL));
+ ScreenLocker* locker =
+ 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();
« no previous file with comments | « chrome/browser/chromeos/login/login_browsertest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698