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

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

Issue 8711003: Enable WebUI ScreenLocker for aura by abstracting lock window. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make virtual constructors private and fix order of lock window initialization. Created 9 years, 1 month 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
Index: chrome/browser/chromeos/login/lock_window_gtk.cc
diff --git a/chrome/browser/chromeos/login/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock_window_gtk.cc
similarity index 56%
copy from chrome/browser/chromeos/login/webui_screen_locker.cc
copy to chrome/browser/chromeos/login/lock_window_gtk.cc
index 4294eebde7ec2ff6f1ce5d192798880296cfb24d..37e2ba470392ba358765451356b2e4c891b75174 100644
--- a/chrome/browser/chromeos/login/webui_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock_window_gtk.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/chromeos/login/webui_screen_locker.h"
+#include "chrome/browser/chromeos/login/lock_window_gtk.h"
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
@@ -34,12 +34,10 @@
#include "ui/base/x/x11_util.h"
#include "ui/gfx/screen.h"
#include "ui/views/widget/native_widget_gtk.h"
+#include "ui/views/widget/widget.h"
namespace {
-// URL which corresponds to the login WebUI.
-const char kLoginURL[] = "chrome://oobe/login";
-
// The maximum duration for which locker should try to grab the keyboard and
// mouse and its interval for regrabbing on failure.
const int kMaxGrabFailureSec = 30;
@@ -49,57 +47,6 @@ const int64 kRetryGrabIntervalMs = 500;
// giving up. If we hit the limit, Chrome exits and the session is terminated.
const int kMaxGrabFailures = kMaxGrabFailureSec * 1000 / kRetryGrabIntervalMs;
-// A ScreenLock window that covers entire screen to keep the keyboard
-// focus/events inside the grab widget.
-class LockWindow : public views::NativeWidgetGtk {
- public:
- explicit LockWindow(chromeos::WebUIScreenLocker* webui_screen_locker)
- : views::NativeWidgetGtk(new views::Widget),
- toplevel_focus_widget_(NULL),
- webui_screen_locker_(webui_screen_locker) {
- EnableDoubleBuffer(true);
- }
-
- virtual gboolean OnButtonPress(GtkWidget* widget,
- GdkEventButton* event) OVERRIDE {
- // Never propagate mouse events to parent.
- return true;
- }
-
- virtual void OnDestroy(GtkWidget* object) OVERRIDE {
- VLOG(1) << "OnDestroy: LockWindow destroyed";
- views::NativeWidgetGtk::OnDestroy(object);
- }
-
- virtual void ClearNativeFocus() OVERRIDE {
- DCHECK(toplevel_focus_widget_);
- gtk_widget_grab_focus(toplevel_focus_widget_);
- }
-
- virtual void HandleGtkGrabBroke() OVERRIDE {
- webui_screen_locker_->HandleGtkGrabBroke();
- }
-
- // Sets the widget to move the focus to when clearning the native
- // widget's focus.
- void set_toplevel_focus_widget(GtkWidget* widget) {
- gtk_widget_set_can_focus(widget, TRUE);
- toplevel_focus_widget_ = widget;
- }
-
- private:
- // The widget we set focus to when clearning the focus on native
- // widget. Gdk input is grabbed in WebUIScreenLocker, and resetting the focus
- // by using gtk_window_set_focus seems to confuse gtk and doesn't let focus
- // move to native widget under this.
- GtkWidget* toplevel_focus_widget_;
-
- // The WebUI screen locker.
- chromeos::WebUIScreenLocker* webui_screen_locker_;
-
- DISALLOW_COPY_AND_ASSIGN(LockWindow);
-};
-
// Define separate methods for each error code so that stack trace
// will tell which error the grab failed with.
void FailedWithGrabAlreadyGrabbed() {
@@ -122,30 +69,86 @@ void FailedWithUnknownError() {
namespace chromeos {
+LockWindow* LockWindow::Create() {
+ LockWindowGtk* window = new LockWindowGtk();
+ return window;
+}
+
////////////////////////////////////////////////////////////////////////////////
-// WebUIScreenLocker implementation.
+// LockWindowGtk implementation.
-WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker)
- : ScreenLockerDelegate(screen_locker),
+LockWindowGtk::LockWindowGtk()
+ : views::NativeWidgetGtk(new views::Widget),
+ lock_window_(NULL),
+ grab_widget_(NULL),
drawn_(false),
input_grabbed_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
grab_failure_count_(0),
kbd_grab_status_(GDK_GRAB_INVALID_TIME),
mouse_grab_status_(GDK_GRAB_INVALID_TIME) {
+ Init();
}
-void WebUIScreenLocker::LockScreen(bool unlock_on_input) {
+void LockWindowGtk::SetContentsView(views::View* content) {
+ lock_window_->SetContentsView(content);
+}
+
+void LockWindowGtk::Show(DOMView* dom_view) {
+ lock_window_->Show();
+ // Grab on the RenderWidgetHostView hosting the WebUI login screen.
+ grab_widget_ = dom_view->dom_contents()->tab_contents()->
+ GetRenderWidgetHostView()->GetNativeView();
+ ClearGtkGrab();
+
+ // Call this after lock_window_->Show(); otherwise the 1st invocation
+ // of gdk_xxx_grab() will always fail.
+ TryGrabAllInputs();
+
+ // Add the window to its own group so that its grab won't be stolen if
+ // gtk_grab_add() gets called on behalf on a non-screen-locker widget (e.g.
+ // a modal dialog) -- see http://crosbug.com/8999. We intentionally do this
+ // after calling ClearGtkGrab(), as want to be in the default window group
+ // then so we can break any existing GTK grabs.
+ GtkWindowGroup* window_group = gtk_window_group_new();
+ gtk_window_group_add_window(window_group,
+ GTK_WINDOW(lock_window_->GetNativeView()));
+ g_object_unref(window_group);
+}
+
+views::Widget* LockWindowGtk::GetWidget() {
+ return views::NativeWidgetGtk::GetWidget();
+}
+
+gboolean LockWindowGtk::OnButtonPress(GtkWidget* widget,
+ GdkEventButton* event) {
+ // Never propagate mouse events to parent.
+ return true;
+}
+
+void LockWindowGtk::OnDestroy(GtkWidget* object) {
+ VLOG(1) << "OnDestroy: LockWindow destroyed";
+ views::NativeWidgetGtk::OnDestroy(object);
+}
+
+void LockWindowGtk::ClearNativeFocus() {
+ gtk_widget_grab_focus(window_contents());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// LockWindowGtk private:
+
+void LockWindowGtk::Init() {
static const GdkColor kGdkBlack = {0, 0, 0, 0};
+ EnableDoubleBuffer(true);
gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(NULL));
- LockWindow* lock_window = new LockWindow(this);
- lock_window_ = lock_window->GetWidget();
+ lock_window_ = GetWidget();
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.bounds = bounds;
- params.native_widget = lock_window;
+ params.native_widget = this;
lock_window_->Init(params);
gtk_widget_modify_bg(
lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack);
@@ -153,76 +156,32 @@ void WebUIScreenLocker::LockScreen(bool unlock_on_input) {
g_signal_connect(lock_window_->GetNativeView(), "client-event",
G_CALLBACK(OnClientEventThunk), this);
- // TODO(flackr): Obscure the screen with black / a screensaver if
- // unlock_on_input.
DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView()));
WmIpc::instance()->SetWindowType(
lock_window_->GetNativeView(),
WM_IPC_WINDOW_CHROME_SCREEN_LOCKER,
NULL);
-
- WebUILoginView::Init(lock_window_);
- lock_window_->SetContentsView(this);
- lock_window_->Show();
- OnWindowCreated();
- LoadURL(GURL(kLoginURL));
- // User list consisting of a single logged-in user.
- UserList users(1, &chromeos::UserManager::Get()->logged_in_user());
- login_display_.reset(new WebUILoginDisplay(this));
- login_display_->set_background_bounds(bounds);
- login_display_->set_parent_window(
- GTK_WINDOW(lock_window_->GetNativeView()));
- login_display_->Init(users, false, false);
-
- static_cast<OobeUI*>(GetWebUI())->ShowSigninScreen(login_display_.get());
-
- registrar_.Add(this,
- chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
- content::NotificationService::AllSources());
-
- ClearGtkGrab();
-
- // Call this after lock_window_->Show(); otherwise the 1st invocation
- // of gdk_xxx_grab() will always fail.
- TryGrabAllInputs();
-
- // Add the window to its own group so that its grab won't be stolen if
- // gtk_grab_add() gets called on behalf on a non-screen-locker widget (e.g.
- // a modal dialog) -- see http://crosbug.com/8999. We intentionally do this
- // after calling ClearGtkGrab(), as want to be in the default window group
- // then so we can break any existing GTK grabs.
- GtkWindowGroup* window_group = gtk_window_group_new();
- gtk_window_group_add_window(window_group,
- GTK_WINDOW(lock_window_->GetNativeView()));
- g_object_unref(window_group);
-
- lock_window->set_toplevel_focus_widget(lock_window->window_contents());
}
-void WebUIScreenLocker::OnGrabInputs() {
+void LockWindowGtk::OnGrabInputs() {
DVLOG(1) << "OnGrabInputs";
input_grabbed_ = true;
- if (drawn_)
- ScreenLockReady();
+ if (drawn_ && observer_)
+ observer_->OnLockWindowReady();
}
-void WebUIScreenLocker::OnWindowManagerReady() {
+void LockWindowGtk::OnWindowManagerReady() {
DVLOG(1) << "OnClientEvent: drawn for lock";
drawn_ = true;
- if (input_grabbed_)
- ScreenLockReady();
+ if (input_grabbed_ && observer_)
+ observer_->OnLockWindowReady();
}
-void WebUIScreenLocker::ScreenLockReady() {
- ScreenLockerDelegate::ScreenLockReady();
- SetInputEnabled(true);
-}
-
-void WebUIScreenLocker::ClearGtkGrab() {
+void LockWindowGtk::ClearGtkGrab() {
GtkWidget* current_grab_window;
// Grab gtk input first so that the menu holding gtk grab will
// close itself.
- gtk_grab_add(webui_login_->native_view());
+ gtk_grab_add(grab_widget_);
// Make sure there is no gtk grab widget so that gtk simply propagates
// an event. GTK maintains grab widgets in a linked-list, so we need to
@@ -231,19 +190,18 @@ void WebUIScreenLocker::ClearGtkGrab() {
gtk_grab_remove(current_grab_window);
}
-void WebUIScreenLocker::TryGrabAllInputs() {
- // Grab on the RenderWidgetHostView hosting the WebUI login screen.
- GdkWindow* grab_widget = webui_login_->dom_contents()->tab_contents()->
- GetRenderWidgetHostView()->GetNativeView()->window;
+void LockWindowGtk::TryGrabAllInputs() {
// Grab x server so that we can atomically grab and take
// action when grab fails.
gdk_x11_grab_server();
- gtk_grab_add(webui_login_->native_view());
+ gtk_grab_add(grab_widget_);
if (kbd_grab_status_ != GDK_GRAB_SUCCESS)
- kbd_grab_status_ = gdk_keyboard_grab(grab_widget, FALSE, GDK_CURRENT_TIME);
+ kbd_grab_status_ = gdk_keyboard_grab(grab_widget_->window,
+ FALSE,
+ GDK_CURRENT_TIME);
if (mouse_grab_status_ != GDK_GRAB_SUCCESS) {
mouse_grab_status_ =
- gdk_pointer_grab(grab_widget,
+ gdk_pointer_grab(grab_widget_->window,
FALSE,
static_cast<GdkEventMask>(
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
@@ -262,7 +220,7 @@ void WebUIScreenLocker::TryGrabAllInputs() {
gdk_x11_ungrab_server();
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(&WebUIScreenLocker::TryGrabAllInputs,
+ base::Bind(&LockWindowGtk::TryGrabAllInputs,
weak_factory_.GetWeakPtr()),
kRetryGrabIntervalMs);
} else {
@@ -295,7 +253,7 @@ void WebUIScreenLocker::TryGrabAllInputs() {
}
}
-void WebUIScreenLocker::TryUngrabOtherClients() {
+void LockWindowGtk::TryUngrabOtherClients() {
#if !defined(NDEBUG)
{
int event_base, error_base;
@@ -321,7 +279,6 @@ void WebUIScreenLocker::TryUngrabOtherClients() {
unsigned int mask;
XQueryPointer(display,
ui::GetX11WindowFromGtkWidget(
- static_cast<LockWindow*>(lock_window_->native_widget())->
window_contents()),
&root, &child, &root_x, &root_y,
&win_x, &winy, &mask);
@@ -345,7 +302,7 @@ void WebUIScreenLocker::TryUngrabOtherClients() {
}
}
-void WebUIScreenLocker::HandleGtkGrabBroke() {
+void LockWindowGtk::HandleGtkGrabBroke() {
// 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
@@ -354,107 +311,11 @@ void WebUIScreenLocker::HandleGtkGrabBroke() {
CHECK_NE(GDK_GRAB_SUCCESS, mouse_grab_status_);
}
-void WebUIScreenLocker::OnAuthenticate() {
-}
-
-void WebUIScreenLocker::SetInputEnabled(bool enabled) {
- login_display_->SetUIEnabled(enabled);
- SetStatusAreaEnabled(enabled);
-}
-
-void WebUIScreenLocker::SetSignoutEnabled(bool enabled) {
- // TODO(flackr): Implement (crbug.com/105267).
- NOTIMPLEMENTED();
-}
-
-void WebUIScreenLocker::ShowErrorMessage(const string16& message,
- bool sign_out_only) {
- // TODO(flackr): Use login_display_ to show error message (requires either
- // adding a method to display error strings or strictly passing error ids:
- // crbug.com/105267).
- base::FundamentalValue login_attempts_value(0);
- base::StringValue error_message(message);
- base::StringValue help_link("");
- base::FundamentalValue help_id(0);
- GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.showSignInError",
- login_attempts_value,
- error_message,
- help_link,
- help_id);
-}
-
-void WebUIScreenLocker::ShowCaptchaAndErrorMessage(const GURL& captcha_url,
- const string16& message) {
- ShowErrorMessage(message, true);
-}
-
-void WebUIScreenLocker::ClearErrors() {
- GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
-}
-
-WebUIScreenLocker::~WebUIScreenLocker() {
- DCHECK(lock_window_);
- lock_window_->Close();
-}
-
-void WebUIScreenLocker::OnClientEvent(GtkWidget* widge, GdkEventClient* event) {
+void LockWindowGtk::OnClientEvent(GtkWidget* widge, GdkEventClient* event) {
WmIpc::Message msg;
WmIpc::instance()->DecodeMessage(*event, &msg);
if (msg.type() == WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK)
OnWindowManagerReady();
}
-////////////////////////////////////////////////////////////////////////////////
-// WebUIScreenLocker, content::NotificationObserver implementation:
-
-void WebUIScreenLocker::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- if (type != chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED)
- return;
-
- const User& user = *content::Details<User>(details).ptr();
- login_display_->OnUserImageChanged(user);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WebUIScreenLocker, LoginDisplay::Delegate implementation:
-
-void WebUIScreenLocker::CreateAccount() {
- NOTREACHED();
-}
-
-string16 WebUIScreenLocker::GetConnectedNetworkName() {
- return GetCurrentNetworkName(CrosLibrary::Get()->GetNetworkLibrary());
-}
-
-void WebUIScreenLocker::FixCaptivePortal() {
- NOTREACHED();
-}
-
-void WebUIScreenLocker::CompleteLogin(const std::string& username,
- const std::string& password) {
- NOTREACHED();
-}
-
-void WebUIScreenLocker::Login(const std::string& username,
- const std::string& password) {
- DCHECK(username == chromeos::UserManager::Get()->logged_in_user().email());
-
- chromeos::ScreenLocker::default_screen_locker()->Authenticate(
- ASCIIToUTF16(password));
-}
-
-void WebUIScreenLocker::LoginAsGuest() {
- NOTREACHED();
-}
-
-void WebUIScreenLocker::OnUserSelected(const std::string& username) {
-}
-
-void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
- NOTREACHED();
-}
-
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698