summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/login
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-14 23:48:27 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-14 23:48:27 +0000
commita39c2d1698c0a313ae5924342854a2038a4de2e9 (patch)
tree1af624ab76b385dc77ae16aa0607ab3f96fe660b /chrome/browser/chromeos/login
parent92e4874bf90039f08a262d6bc44c8cc6eba7c430 (diff)
downloadchromium_src-a39c2d1698c0a313ae5924342854a2038a4de2e9.zip
chromium_src-a39c2d1698c0a313ae5924342854a2038a4de2e9.tar.gz
chromium_src-a39c2d1698c0a313ae5924342854a2038a4de2e9.tar.bz2
Hook up ScreenLocker to screen lock cros library.
* Added ScreenLockerLibrary and its mock class. * Call NotifyScreenLockCompleted when screen locker is shown * Call NotifyScreenUnlocked when authentication is sucessful. * Replace includes in cros_in_process_browser_test.cc with forward declarations. * Added ScreenLockerTester for testing * Added new browser test ScreenLockerTest.TestBasic BUG=2914 TEST=added ScreenLockerTest.TestBasic browser test. Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=47216 Review URL: http://codereview.chromium.org/2025009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47338 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/login')
-rw-r--r--chrome/browser/chromeos/login/login_manager_view_browsertest.cc1
-rw-r--r--chrome/browser/chromeos/login/screen_lock_view.h6
-rw-r--r--chrome/browser/chromeos/login/screen_locker.cc80
-rw-r--r--chrome/browser/chromeos/login/screen_locker.h28
-rw-r--r--chrome/browser/chromeos/login/screen_locker_browsertest.cc59
-rw-r--r--chrome/browser/chromeos/login/screen_locker_tester.cc53
-rw-r--r--chrome/browser/chromeos/login/screen_locker_tester.h48
7 files changed, 257 insertions, 18 deletions
diff --git a/chrome/browser/chromeos/login/login_manager_view_browsertest.cc b/chrome/browser/chromeos/login/login_manager_view_browsertest.cc
index a4e7ba4..1f062d8 100644
--- a/chrome/browser/chromeos/login/login_manager_view_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_manager_view_browsertest.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
#include "chrome/browser/chromeos/cros/mock_login_library.h"
+#include "chrome/browser/chromeos/cros/mock_network_library.h"
#include "chrome/browser/chromeos/login/login_manager_view.h"
#include "chrome/browser/chromeos/login/mock_authenticator.h"
#include "chrome/browser/chromeos/login/mock_screen_observer.h"
diff --git a/chrome/browser/chromeos/login/screen_lock_view.h b/chrome/browser/chromeos/login/screen_lock_view.h
index 9d94cfb..49de5a2 100644
--- a/chrome/browser/chromeos/login/screen_lock_view.h
+++ b/chrome/browser/chromeos/login/screen_lock_view.h
@@ -19,6 +19,10 @@ namespace chromeos {
class ScreenLocker;
+namespace test {
+class ScreenLockerTester;
+} // namespace test
+
// ScreenLockView creates view components necessary to authenticate
// a user to unlock the screen.
class ScreenLockView : public views::View,
@@ -52,6 +56,8 @@ class ScreenLockView : public views::View,
const views::Textfield::Keystroke& keystroke);
private:
+ friend class test::ScreenLockerTester;
+
// Set the user's image.
void SetImage(const SkBitmap& image,
int desired_width,
diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc
index de7cd88..d4f5eeb 100644
--- a/chrome/browser/chromeos/login/screen_locker.cc
+++ b/chrome/browser/chromeos/login/screen_locker.cc
@@ -6,16 +6,57 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "base/singleton.h"
#include "base/utf_string_conversions.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/screen_lock_view.h"
+#include "chrome/common/notification_service.h"
#include "views/screen.h"
#include "views/widget/widget_gtk.h"
namespace {
+// Observer to start ScreenLocker when the screen lock
+class ScreenLockObserver : public chromeos::ScreenLockLibrary::Observer,
+ public NotificationObserver {
+ public:
+ ScreenLockObserver() {
+ registrar_.Add(this, NotificationType::LOGIN_USER_CHANGED,
+ NotificationService::AllSources());
+ }
+
+ // NotificationObserver overrides:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::LOGIN_USER_CHANGED) {
+ // Register Screen Lock after login screen to make sure
+ // we don't show the screen lock on top of the login screen by accident.
+ if (chromeos::CrosLibrary::Get()->EnsureLoaded())
+ chromeos::CrosLibrary::Get()->GetScreenLockLibrary()->AddObserver(this);
+ }
+ }
+
+ virtual void ScreenLocked(chromeos::ScreenLockLibrary* obj) {
+ chromeos::ScreenLocker::Show();
+ }
+
+ private:
+ NotificationRegistrar registrar_;
+
+ 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 {
@@ -25,7 +66,6 @@ class GrabWidget : public views::WidgetGtk {
virtual void Show() {
views::WidgetGtk::Show();
-
GtkWidget* current_grab_window = gtk_grab_get_current();
if (current_grab_window)
gtk_grab_remove(current_grab_window);
@@ -34,7 +74,7 @@ class GrabWidget : public views::WidgetGtk {
GdkGrabStatus kbd_status =
gdk_keyboard_grab(window_contents()->window, FALSE,
GDK_CURRENT_TIME);
- CHECK_EQ(kbd_status, GDK_GRAB_SUCCESS) << "Failed to grab keyboard input";
+ CHECK_EQ(GDK_GRAB_SUCCESS, kbd_status) << "Failed to grab keyboard input";
GdkGrabStatus ptr_status =
gdk_pointer_grab(window_contents()->window,
FALSE,
@@ -44,7 +84,7 @@ class GrabWidget : public views::WidgetGtk {
NULL,
NULL,
GDK_CURRENT_TIME);
- CHECK_EQ(ptr_status, GDK_GRAB_SUCCESS) << "Failed to grab pointer input";
+ CHECK_EQ(GDK_GRAB_SUCCESS, ptr_status) << "Failed to grab pointer input";
}
private:
@@ -60,24 +100,28 @@ ScreenLocker::ScreenLocker(const UserManager::User& user)
lock_widget_(NULL),
screen_lock_view_(NULL),
user_(user) {
+ DCHECK(!screen_locker_);
+ screen_locker_ = this;
}
ScreenLocker::~ScreenLocker() {
DCHECK(lock_window_);
lock_window_->Close();
// lock_widget_ will be deleted by gtk's destroy signal.
+ screen_locker_ = NULL;
+ if (CrosLibrary::Get()->EnsureLoaded())
+ CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenUnlocked();
}
void ScreenLocker::Init(const gfx::Rect& bounds) {
// TODO(oshima): Figure out which UI to keep and remove in the background.
- views::View* screen = new chromeos::BackgroundView();
+ views::View* screen = new BackgroundView();
lock_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
lock_window_->Init(NULL, bounds);
lock_window_->SetContentsView(screen);
lock_window_->Show();
- authenticator_ =
- LoginUtils::Get()->CreateAuthenticator(this);
+ authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
screen_lock_view_ = new ScreenLockView(this);
screen_lock_view_->Init();
@@ -123,17 +167,25 @@ void ScreenLocker::Authenticate(const string16& password) {
UTF16ToUTF8(password)));
}
-} // namespace chromeos
-
-namespace browser {
-
-void ShowScreenLock() {
+// static
+void ScreenLocker::Show() {
DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
+ if (screen_locker_) {
+ LOG(INFO) << "ScreenLocker is already open. Ignoring request.";
+ return;
+ }
gfx::Rect bounds(views::Screen::GetMonitorWorkAreaNearestWindow(NULL));
- chromeos::ScreenLocker* locker = new chromeos::ScreenLocker(
- chromeos::UserManager::Get()->logged_in_user());
+ 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();
}
-} // namespace browser
+void ScreenLocker::InitClass() {
+ Singleton<ScreenLockObserver>::get();
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screen_locker.h b/chrome/browser/chromeos/login/screen_locker.h
index 4d1e53f..213a75d 100644
--- a/chrome/browser/chromeos/login/screen_locker.h
+++ b/chrome/browser/chromeos/login/screen_locker.h
@@ -24,12 +24,16 @@ namespace chromeos {
class Authenticator;
class ScreenLockView;
+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:
- ScreenLocker(const UserManager::User& user);
+ explicit ScreenLocker(const UserManager::User& user);
// Initialize and show the screen locker with given |bounds|.
void Init(const gfx::Rect& bounds);
@@ -42,19 +46,31 @@ class ScreenLocker : public LoginStatusConsumer {
// Authenticates the user with given |password| and authenticator.
void Authenticate(const string16& password);
- // Sets the authenticator.
- void SetAuthenticator(Authenticator* authenticator);
-
// Returns the user to authenticate.
const UserManager::User& user() const {
return user_;
}
+ // 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. Does nothing if it's already opened.
+ static void Show();
+
+ // Returns the tester
+ static test::ScreenLockerTester* GetTester();
+
private:
friend class DeleteTask<ScreenLocker>;
+ friend class test::ScreenLockerTester;
virtual ~ScreenLocker();
+ // Sets the authenticator.
+ void SetAuthenticator(Authenticator* authenticator);
+
// The screen locker window.
views::WidgetGtk* lock_window_;
@@ -70,6 +86,10 @@ class ScreenLocker : public LoginStatusConsumer {
// Used for logging in.
scoped_refptr<Authenticator> authenticator_;
+ // 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_;
+
DISALLOW_COPY_AND_ASSIGN(ScreenLocker);
};
diff --git a/chrome/browser/chromeos/login/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/screen_locker_browsertest.cc
new file mode 100644
index 0000000..578771a
--- /dev/null
+++ b/chrome/browser/chromeos/login/screen_locker_browsertest.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2010 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.
+
+#include "base/message_loop.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
+#include "chrome/browser/chromeos/cros/mock_screen_lock_library.h"
+#include "chrome/browser/chromeos/login/screen_locker.h"
+#include "chrome/browser/chromeos/login/screen_locker_tester.h"
+#include "chrome/browser/chromeos/login/mock_authenticator.h"
+#include "chrome/browser/views/browser_dialogs.h"
+#include "chrome/test/ui_test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "views/controls/textfield/textfield.h"
+
+namespace chromeos {
+
+class ScreenLockerTest : public CrosInProcessBrowserTest {
+ public:
+ ScreenLockerTest() {}
+
+ private:
+ virtual void SetUpInProcessBrowserTestFixture() {
+ InitStatusAreaMocks();
+ InitMockScreenLockLibrary();
+ EXPECT_CALL(*mock_screen_lock_library_, NotifyScreenLockCompleted())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*mock_screen_lock_library_, NotifyScreenUnlocked())
+ .Times(1)
+ .RetiresOnSaturation();
+
+ // Expectations for the status are on the screen lock window.
+ SetStatusAreaMocksExpectations();
+ // Expectations for the status area on the browser window.
+ SetStatusAreaMocksExpectations();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenLockerTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestBasic) {
+ ScreenLocker::Show();
+ ui_test_utils::RunAllPendingInMessageLoop();
+ scoped_ptr<test::ScreenLockerTester> tester(ScreenLocker::GetTester());
+ tester->InjectMockAuthenticator("pass");
+ EXPECT_TRUE(tester->IsOpen());
+ tester->EnterPassword("fail");
+ ui_test_utils::RunAllPendingInMessageLoop();
+ EXPECT_TRUE(tester->IsOpen());
+ tester->EnterPassword("pass");
+ ui_test_utils::RunAllPendingInMessageLoop();
+ EXPECT_TRUE(!tester->IsOpen());
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screen_locker_tester.cc b/chrome/browser/chromeos/login/screen_locker_tester.cc
new file mode 100644
index 0000000..776aa6a
--- /dev/null
+++ b/chrome/browser/chromeos/login/screen_locker_tester.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 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.
+
+#include "chrome/browser/chromeos/login/screen_locker_tester.h"
+
+#include <gdk/gdkkeysyms.h>
+
+#include "app/l10n_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/chromeos/login/mock_authenticator.h"
+#include "chrome/browser/chromeos/login/screen_locker.h"
+#include "chrome/browser/chromeos/login/screen_lock_view.h"
+#include "views/controls/button/button.h"
+#include "views/controls/label.h"
+#include "views/controls/textfield/textfield.h"
+
+namespace chromeos {
+
+test::ScreenLockerTester* ScreenLocker::GetTester() {
+ return new test::ScreenLockerTester();
+}
+
+namespace test {
+
+bool ScreenLockerTester::IsOpen() {
+ return chromeos::ScreenLocker::screen_locker_ != NULL;
+}
+
+void ScreenLockerTester::InjectMockAuthenticator(const char* password) {
+ DCHECK(ScreenLocker::screen_locker_);
+ ScreenLocker::screen_locker_->SetAuthenticator(
+ new MockAuthenticator(ScreenLocker::screen_locker_, "", password));
+}
+
+void ScreenLockerTester::EnterPassword(const char* password) {
+ DCHECK(ScreenLocker::screen_locker_);
+ views::Textfield* pass = GetPasswordField();
+ pass->SetText(ASCIIToUTF16(password));
+ GdkEventKey eventKey;
+ eventKey.keyval = GDK_Return;
+ views::Textfield::Keystroke ret(&eventKey);
+ ScreenLocker::screen_locker_->screen_lock_view_->HandleKeystroke(pass, ret);
+}
+
+views::Textfield* ScreenLockerTester::GetPasswordField() {
+ DCHECK(ScreenLocker::screen_locker_);
+ return ScreenLocker::screen_locker_->screen_lock_view_->password_field_;
+}
+
+} // namespace test
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screen_locker_tester.h b/chrome/browser/chromeos/login/screen_locker_tester.h
new file mode 100644
index 0000000..06b960e
--- /dev/null
+++ b/chrome/browser/chromeos/login/screen_locker_tester.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 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_TESTER_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_LOCKER_TESTER_H_
+
+#include "base/basictypes.h"
+
+namespace views {
+class Button;
+class Textfield;
+} // namespace views
+
+namespace chromeos {
+
+class ScreenLocker;
+
+namespace test {
+
+// ScreenLockerTester provides access to the private state/function
+// of ScreenLocker class. Used to implement unit tests.
+class ScreenLockerTester {
+ public:
+ // Returns true if the screen lock is open.
+ bool IsOpen();
+
+ // Injects MockAuthenticate that uses given password .
+ void InjectMockAuthenticator(const char* password);
+
+ // Emulates entring a password.
+ void EnterPassword(const char* password);
+
+ private:
+ friend class chromeos::ScreenLocker;
+
+ ScreenLockerTester() {}
+
+ views::Textfield* GetPasswordField();
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenLockerTester);
+};
+
+} // namespace test
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_LOCKER_TESTER_H_