diff options
19 files changed, 494 insertions, 25 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index c32e0d1..5d05685 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -143,7 +143,9 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/cros/screen_lock_library.h" #include "chrome/browser/chromeos/external_metrics.h" +#include "chrome/browser/chromeos/login/screen_locker.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/views/browser_dialogs.h" #endif @@ -603,6 +605,7 @@ void OptionallyRunChromeOSLoginManager(const CommandLine& parsed_command_line) { } browser::ShowLoginWizard(first_screen, size); } + chromeos::ScreenLocker::InitClass(); } #else void OptionallyRunChromeOSLoginManager(const CommandLine& parsed_command_line) { diff --git a/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc b/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc index 73d74f0..7128a9b 100644 --- a/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc +++ b/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc @@ -9,6 +9,13 @@ #include "base/time.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" +#include "chrome/browser/chromeos/cros/mock_language_library.h" +#include "chrome/browser/chromeos/cros/mock_library_loader.h" +#include "chrome/browser/chromeos/cros/mock_network_library.h" +#include "chrome/browser/chromeos/cros/mock_power_library.h" +#include "chrome/browser/chromeos/cros/mock_screen_lock_library.h" +#include "chrome/browser/chromeos/cros/mock_synaptics_library.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/login/wizard_screen.h" #include "chrome/test/in_process_browser_test.h" @@ -29,6 +36,7 @@ CrosInProcessBrowserTest::CrosInProcessBrowserTest() mock_language_library_(NULL), mock_network_library_(NULL), mock_power_library_(NULL), + mock_screen_lock_library_(NULL), mock_synaptics_library_(NULL) {} CrosInProcessBrowserTest::~CrosInProcessBrowserTest() { @@ -87,6 +95,14 @@ void CrosInProcessBrowserTest::InitMockPowerLibrary() { test_api()->SetPowerLibrary(mock_power_library_, true); } +void CrosInProcessBrowserTest::InitMockScreenLockLibrary() { + InitMockLibraryLoader(); + if (mock_screen_lock_library_) + return; + mock_screen_lock_library_ = new MockScreenLockLibrary(); + test_api()->SetScreenLockLibrary(mock_screen_lock_library_, true); +} + void CrosInProcessBrowserTest::InitMockSynapticsLibrary() { InitMockLibraryLoader(); if (mock_synaptics_library_) @@ -208,6 +224,8 @@ void CrosInProcessBrowserTest::TearDownInProcessBrowserTestFixture() { test_api()->SetNetworkLibrary(NULL, false); if (mock_power_library_) test_api()->SetPowerLibrary(NULL, false); + if (mock_screen_lock_library_) + test_api()->SetScreenLockLibrary(NULL, false); if (mock_synaptics_library_) test_api()->SetSynapticsLibrary(NULL, false); } diff --git a/chrome/browser/chromeos/cros/cros_in_process_browser_test.h b/chrome/browser/chromeos/cros/cros_in_process_browser_test.h index 524ad93..f46c2ce 100644 --- a/chrome/browser/chromeos/cros/cros_in_process_browser_test.h +++ b/chrome/browser/chromeos/cros/cros_in_process_browser_test.h @@ -7,17 +7,20 @@ #include "base/scoped_ptr.h" #include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" -#include "chrome/browser/chromeos/cros/mock_language_library.h" -#include "chrome/browser/chromeos/cros/mock_library_loader.h" -#include "chrome/browser/chromeos/cros/mock_network_library.h" -#include "chrome/browser/chromeos/cros/mock_power_library.h" -#include "chrome/browser/chromeos/cros/mock_synaptics_library.h" #include "chrome/test/in_process_browser_test.h" #include "third_party/cros/chromeos_language.h" namespace chromeos { +class MockLibraryLoader; +class MockScreenLockLibrary; +class MockCryptohomeLibrary; +class MockLanguageLibrary; +class MockNetworkLibrary; +class MockPowerLibrary; +class MockScreenLockLibrary; +class MockSynapticsLibrary; + // Base class for Chromium OS tests wanting to bring up a browser in the // unit test process and mock some parts of CrosLibrary. Once you mock part of // CrosLibrary it will be considered as successfully loaded and libraries @@ -47,6 +50,7 @@ class CrosInProcessBrowserTest : public InProcessBrowserTest { void InitMockLanguageLibrary(); void InitMockNetworkLibrary(); void InitMockPowerLibrary(); + void InitMockScreenLockLibrary(); void InitMockSynapticsLibrary(); // This method setups corresponding expectations for basic mocks that @@ -75,6 +79,7 @@ class CrosInProcessBrowserTest : public InProcessBrowserTest { MockLanguageLibrary* mock_language_library_; MockNetworkLibrary* mock_network_library_; MockPowerLibrary* mock_power_library_; + MockScreenLockLibrary* mock_screen_lock_library_; MockSynapticsLibrary* mock_synaptics_library_; ImePropertyList ime_properties_; diff --git a/chrome/browser/chromeos/cros/cros_library.cc b/chrome/browser/chromeos/cros/cros_library.cc index 5fafab8..c44fe43 100644 --- a/chrome/browser/chromeos/cros/cros_library.cc +++ b/chrome/browser/chromeos/cros/cros_library.cc @@ -11,6 +11,7 @@ #include "chrome/browser/chromeos/cros/mount_library.h" #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/chromeos/cros/power_library.h" +#include "chrome/browser/chromeos/cros/screen_lock_library.h" #include "chrome/browser/chromeos/cros/speech_synthesis_library.h" #include "chrome/browser/chromeos/cros/synaptics_library.h" @@ -23,6 +24,7 @@ CrosLibrary::CrosLibrary() : library_loader_(NULL), mount_lib_(NULL), network_lib_(NULL), power_lib_(NULL), + screen_lock_lib_(NULL), speech_synthesis_lib_(NULL), synaptics_lib_(NULL), own_library_loader_(true), @@ -55,6 +57,8 @@ CrosLibrary::~CrosLibrary() { delete network_lib_; if (own_power_loader_ && power_lib_) delete power_lib_; + if (own_screen_lock_lib_ && screen_lock_lib_) + delete screen_lock_lib_; if (own_speech_synthesis_library_ && speech_synthesis_lib_) delete speech_synthesis_lib_; if (own_synaptics_library_ && synaptics_lib_) @@ -104,6 +108,12 @@ PowerLibrary* CrosLibrary::GetPowerLibrary() { return power_lib_; } +ScreenLockLibrary* CrosLibrary::GetScreenLockLibrary() { + if (!screen_lock_lib_) + screen_lock_lib_ = new ScreenLockLibraryImpl(); + return screen_lock_lib_; +} + SpeechSynthesisLibrary* CrosLibrary::GetSpeechSynthesisLibrary() { if (!speech_synthesis_lib_) speech_synthesis_lib_ = new SpeechSynthesisLibraryImpl(); @@ -190,6 +200,14 @@ void CrosLibrary::TestApi::SetPowerLibrary(PowerLibrary* library, bool own) { library_->power_lib_ = library; } +void CrosLibrary::TestApi::SetScreenLockLibrary(ScreenLockLibrary* library, + bool own) { + if (library_->own_screen_lock_lib_ && library_->screen_lock_lib_) + delete library_->screen_lock_lib_; + library_->own_screen_lock_lib_ = own; + library_->screen_lock_lib_ = library; +} + void CrosLibrary::TestApi::SetSpeechSynthesisLibrary( SpeechSynthesisLibrary* library, bool own) { if (library_->own_speech_synthesis_library_ && diff --git a/chrome/browser/chromeos/cros/cros_library.h b/chrome/browser/chromeos/cros/cros_library.h index 9578883..035ab4d 100644 --- a/chrome/browser/chromeos/cros/cros_library.h +++ b/chrome/browser/chromeos/cros/cros_library.h @@ -18,6 +18,7 @@ class LoginLibrary; class MountLibrary; class NetworkLibrary; class PowerLibrary; +class ScreenLockLibrary; class SpeechSynthesisLibrary; class SynapticsLibrary; @@ -48,6 +49,8 @@ class CrosLibrary { void SetNetworkLibrary(NetworkLibrary* library, bool own); // Setter for PowerLibrary. void SetPowerLibrary(PowerLibrary* library, bool own); + // Setter for ScreenLockLibrary. + void SetScreenLockLibrary(ScreenLockLibrary* library, bool own); // Setter for SpeechSynthesisLibrary. void SetSpeechSynthesisLibrary(SpeechSynthesisLibrary* library, bool own); // Setter for SynapticsLibrary. @@ -80,6 +83,9 @@ class CrosLibrary { // Getter for PowerLibrary PowerLibrary* GetPowerLibrary(); + // Getter for ScreenLockLibrary + ScreenLockLibrary* GetScreenLockLibrary(); + // This gets the singleton SpeechSynthesisLibrary. SpeechSynthesisLibrary* GetSpeechSynthesisLibrary(); @@ -112,6 +118,7 @@ class CrosLibrary { MountLibrary* mount_lib_; NetworkLibrary* network_lib_; PowerLibrary* power_lib_; + ScreenLockLibrary* screen_lock_lib_; SpeechSynthesisLibrary* speech_synthesis_lib_; SynapticsLibrary* synaptics_lib_; @@ -122,6 +129,7 @@ class CrosLibrary { bool own_mount_loader_; bool own_network_loader_; bool own_power_loader_; + bool own_screen_lock_lib_; bool own_speech_synthesis_library_; bool own_synaptics_library_; diff --git a/chrome/browser/chromeos/cros/mock_screen_lock_library.h b/chrome/browser/chromeos/cros/mock_screen_lock_library.h new file mode 100644 index 0000000..7043c28 --- /dev/null +++ b/chrome/browser/chromeos/cros/mock_screen_lock_library.h @@ -0,0 +1,27 @@ +// 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_CROS_MOCK_SCREEN_LOCK_LIBRARY_H_ +#define CHROME_BROWSER_CHROMEOS_CROS_MOCK_SCREEN_LOCK_LIBRARY_H_ + +#include "chrome/browser/chromeos/cros/screen_lock_library.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace chromeos { + +class MockScreenLockLibrary : public ScreenLockLibrary { + public: + MockScreenLockLibrary() {} + virtual ~MockScreenLockLibrary() {} + MOCK_METHOD1(AddObserver, void(Observer*)); + MOCK_METHOD1(RemoveObserver, void(Observer*)); + + MOCK_METHOD0(NotifyScreenLockCompleted, void()); + MOCK_METHOD0(NotifyScreenLockRequested, void()); + MOCK_METHOD0(NotifyScreenUnlocked, void()); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_CROS_MOCK_SCREEN_LOCK_LIBRARY_H_ diff --git a/chrome/browser/chromeos/cros/screen_lock_library.cc b/chrome/browser/chromeos/cros/screen_lock_library.cc new file mode 100644 index 0000000..84c01c0 --- /dev/null +++ b/chrome/browser/chromeos/cros/screen_lock_library.cc @@ -0,0 +1,76 @@ +// 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/cros/screen_lock_library.h" + +#include "base/message_loop.h" +#include "base/string_util.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/chromeos/cros/cros_library.h" + +// Allows InvokeLater without adding refcounting. This class is a Singleton and +// won't be deleted until it's last InvokeLater is run. +template <> +struct RunnableMethodTraits<chromeos::ScreenLockLibraryImpl> { + void RetainCallee(chromeos::ScreenLockLibraryImpl* obj) {} + void ReleaseCallee(chromeos::ScreenLockLibraryImpl* obj) {} +}; + +namespace chromeos { + +ScreenLockLibraryImpl::ScreenLockLibraryImpl() { + if (CrosLibrary::Get()->EnsureLoaded()) { + Init(); + } +} + +ScreenLockLibraryImpl::~ScreenLockLibraryImpl() { + if (screen_lock_connection_) { + chromeos::DisconnectScreenLock(screen_lock_connection_); + } +} + +void ScreenLockLibraryImpl::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void ScreenLockLibraryImpl::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void ScreenLockLibraryImpl::NotifyScreenLockCompleted() { + chromeos::NotifyScreenLockCompleted(); +} + +void ScreenLockLibraryImpl::NotifyScreenLockRequested() { + chromeos::NotifyScreenLockRequested(); +} + +void ScreenLockLibraryImpl::NotifyScreenUnlocked() { + chromeos::NotifyScreenUnlocked(); +} + +void ScreenLockLibraryImpl::Init() { + screen_lock_connection_ = chromeos::MonitorScreenLock( + &ScreenLockedHandler, this); +} + +void ScreenLockLibraryImpl::ScreenLocked() { + // Make sure we run on UI thread. + if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableMethod(this, &ScreenLockLibraryImpl::ScreenLocked)); + return; + } + FOR_EACH_OBSERVER(Observer, observers_, ScreenLocked(this)); +} + +// static +void ScreenLockLibraryImpl::ScreenLockedHandler(void* object) { + ScreenLockLibraryImpl* self = static_cast<ScreenLockLibraryImpl*>(object); + self->ScreenLocked(); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/cros/screen_lock_library.h b/chrome/browser/chromeos/cros/screen_lock_library.h new file mode 100644 index 0000000..f36ca80 --- /dev/null +++ b/chrome/browser/chromeos/cros/screen_lock_library.h @@ -0,0 +1,70 @@ +// 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_CROS_SCREEN_LOCK_LIBRARY_H_ +#define CHROME_BROWSER_CHROMEOS_CROS_SCREEN_LOCK_LIBRARY_H_ + +#include "base/observer_list.h" +#include "third_party/cros/chromeos_screen_lock.h" + +namespace chromeos { + +// This interface defines interaction with the ChromeOS screen lock +// APIs. +class ScreenLockLibrary { + public: + class Observer { + public: + virtual ~Observer() {} + virtual void ScreenLocked(ScreenLockLibrary* obj) = 0; + }; + ScreenLockLibrary() {} + virtual ~ScreenLockLibrary() {} + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Notifies PowerManager that screen lock has been completed. + virtual void NotifyScreenLockCompleted() = 0; + // Notifies PowerManager that a user requested to lock the screen. + virtual void NotifyScreenLockRequested() = 0; + // Notifies PowerManager that a user unlocked the screen. + virtual void NotifyScreenUnlocked() = 0; +}; + +// This class handles the interaction with the ChromeOS screen lock APIs. +class ScreenLockLibraryImpl : public ScreenLockLibrary { + public: + ScreenLockLibraryImpl(); + virtual ~ScreenLockLibraryImpl(); + + // ScreenLockLibrary implementations: + virtual void AddObserver(Observer* observer); + virtual void RemoveObserver(Observer* observer); + virtual void NotifyScreenLockCompleted(); + virtual void NotifyScreenLockRequested(); + virtual void NotifyScreenUnlocked(); + + private: + // This method is called when PowerManager requests to lock the screen. + // This method is called on a background thread. + static void ScreenLockedHandler(void* object); + + // This methods starts the monitoring of screen lock request. + void Init(); + + // Called by the handler to notify the screen lock request from + // PowerManager. + void ScreenLocked(); + + ObserverList<Observer> observers_; + + // A reference to the screen lock api + chromeos::ScreenLockConnection screen_lock_connection_; + + DISALLOW_COPY_AND_ASSIGN(ScreenLockLibraryImpl); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_CROS_SCREEN_LOCK_LIBRARY_H_ 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.cc b/chrome/browser/chromeos/login/screen_lock_view.cc index 1aa7bca..bfb00ea 100644 --- a/chrome/browser/chromeos/login/screen_lock_view.cc +++ b/chrome/browser/chromeos/login/screen_lock_view.cc @@ -183,4 +183,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 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..b50d20e 100644 --- a/chrome/browser/chromeos/login/screen_locker.cc +++ b/chrome/browser/chromeos/login/screen_locker.cc @@ -6,16 +6,58 @@ #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(new ScreenLockObserver())); + } + } + + 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 +67,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 +75,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 +85,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 +101,27 @@ ScreenLocker::ScreenLocker(const UserManager::User& user) lock_widget_(NULL), screen_lock_view_(NULL), user_(user) { + 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 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..575cc69 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 nothign 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_ diff --git a/chrome/browser/views/browser_dialogs.h b/chrome/browser/views/browser_dialogs.h index 31604c5..4fa37be 100644 --- a/chrome/browser/views/browser_dialogs.h +++ b/chrome/browser/views/browser_dialogs.h @@ -29,6 +29,7 @@ class TemplateURL; namespace gfx { class Rect; +class Size; } // namespace gfx namespace views { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 2ae62f0..b192909 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -353,6 +353,8 @@ 'browser/chromeos/cros/network_library.h', 'browser/chromeos/cros/power_library.cc', 'browser/chromeos/cros/power_library.h', + 'browser/chromeos/cros/screen_lock_library.cc', + 'browser/chromeos/cros/screen_lock_library.h', 'browser/chromeos/cros/speech_synthesis_library.cc', 'browser/chromeos/cros/speech_synthesis_library.h', 'browser/chromeos/cros/synaptics_library.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index c372b76..f18f78b 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1441,6 +1441,9 @@ 'browser/chromeos/login/login_manager_view_browsertest.cc', 'browser/chromeos/login/mock_authenticator.h', 'browser/chromeos/login/network_screen_browsertest.cc', + 'browser/chromeos/login/screen_locker_browsertest.cc', + 'browser/chromeos/login/screen_locker_tester.cc', + 'browser/chromeos/login/screen_locker_tester.h', 'browser/chromeos/login/wizard_controller_browsertest.cc', 'browser/chromeos/notifications/notification_browsertest.cc', 'browser/chromeos/options/wifi_config_view_browsertest.cc', |