From af3e429b08a24b795cd538363c4d75b654e26e98 Mon Sep 17 00:00:00 2001 From: "shuchen@chromium.org" Date: Mon, 16 Jun 2014 20:09:57 +0000 Subject: [PATCH] Notifies capslock state changed in fake ime keyboard. BUG=375586 TEST=Verified on Pixel device and linux_chromeos. Review URL: https://codereview.chromium.org/334863002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277524 0039d316-1c4b-4281-b951-d872f2087c98 --- ash/system/chromeos/tray_caps_lock.cc | 43 +++++++------------ ash/system/chromeos/tray_caps_lock.h | 4 -- .../chromeos/login/signin_screen_handler.cc | 25 +++-------- .../chromeos/login/signin_screen_handler.h | 4 -- chromeos/ime/fake_ime_keyboard.cc | 10 +++++ chromeos/ime/fake_ime_keyboard.h | 5 ++- chromeos/ime/ime_keyboard_x11_unittest.cc | 28 +++++++++++- ui/base/ime/input_method_chromeos.cc | 20 +++++++++ 8 files changed, 81 insertions(+), 58 deletions(-) diff --git a/ash/system/chromeos/tray_caps_lock.cc b/ash/system/chromeos/tray_caps_lock.cc index 7c9925d558b6b2..0c83ea489094fd 100644 --- a/ash/system/chromeos/tray_caps_lock.cc +++ b/ash/system/chromeos/tray_caps_lock.cc @@ -111,11 +111,13 @@ class CapsLockDefaultView : public ActionableView { virtual bool PerformAction(const ui::Event& event) OVERRIDE { chromeos::input_method::ImeKeyboard* keyboard = chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); - Shell::GetInstance()->metrics()->RecordUserMetricsAction( - keyboard->CapsLockIsEnabled() ? - ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK : - ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK); - keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled()); + if (keyboard) { + Shell::GetInstance()->metrics()->RecordUserMetricsAction( + keyboard->CapsLockIsEnabled() ? + ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK : + ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK); + keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled()); + } return true; } @@ -131,27 +133,17 @@ TrayCapsLock::TrayCapsLock(SystemTray* system_tray) detailed_(NULL), caps_lock_enabled_(CapsLockIsEnabled()), message_shown_(false) { - // Since keyboard handling differs between ChromeOS and Linux we need to - // use different observers depending on the two platforms. - if (base::SysInfo::IsRunningOnChromeOS()) { - chromeos::input_method::ImeKeyboard* keyboard = - chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); - keyboard->AddObserver(this); - } else { - Shell::GetInstance()->PrependPreTargetHandler(this); - } + chromeos::input_method::InputMethodManager* ime = + chromeos::input_method::InputMethodManager::Get(); + if (ime && ime->GetImeKeyboard()) + ime->GetImeKeyboard()->AddObserver(this); } TrayCapsLock::~TrayCapsLock() { - // Since keyboard handling differs between ChromeOS and Linux we need to - // use different observers depending on the two platforms. - if (base::SysInfo::IsRunningOnChromeOS()) { - chromeos::input_method::ImeKeyboard* keyboard = - chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); - keyboard->RemoveObserver(this); - } else { - Shell::GetInstance()->RemovePreTargetHandler(this); - } + chromeos::input_method::InputMethodManager* ime = + chromeos::input_method::InputMethodManager::Get(); + if (ime && ime->GetImeKeyboard()) + ime->GetImeKeyboard()->RemoveObserver(this); } void TrayCapsLock::OnCapsLockChanged(bool enabled) { @@ -176,11 +168,6 @@ void TrayCapsLock::OnCapsLockChanged(bool enabled) { } } -void TrayCapsLock::OnKeyEvent(ui::KeyEvent* key) { - if (key->type() == ui::ET_KEY_PRESSED && key->key_code() == ui::VKEY_CAPITAL) - OnCapsLockChanged(!caps_lock_enabled_); -} - bool TrayCapsLock::GetInitialVisibility() { return CapsLockIsEnabled(); } diff --git a/ash/system/chromeos/tray_caps_lock.h b/ash/system/chromeos/tray_caps_lock.h index 74eea29b105330..0343126e545194 100644 --- a/ash/system/chromeos/tray_caps_lock.h +++ b/ash/system/chromeos/tray_caps_lock.h @@ -18,7 +18,6 @@ namespace ash { class CapsLockDefaultView; class TrayCapsLock : public TrayImageItem, - public ui::EventHandler, public chromeos::input_method::ImeKeyboard::Observer { public: explicit TrayCapsLock(SystemTray* system_tray); @@ -28,9 +27,6 @@ class TrayCapsLock : public TrayImageItem, // Overriden from chromeos::input_method::ImeKeyboard::Observer: virtual void OnCapsLockChanged(bool enabled) OVERRIDE; - // ui::EventHandler: - virtual void OnKeyEvent(ui::KeyEvent* key) OVERRIDE; - // Overridden from TrayImageItem. virtual bool GetInitialVisibility() OVERRIDE; virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 1c761365153bea..e0cf0ce408f25e 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc @@ -273,25 +273,17 @@ SigninScreenHandler::SigninScreenHandler( chrome::NOTIFICATION_AUTH_CANCELLED, content::NotificationService::AllSources()); - // Since keyboard handling differs between ChromeOS and Linux we need to - // use different observers depending on the two platforms. - if (base::SysInfo::IsRunningOnChromeOS()) { - chromeos::input_method::ImeKeyboard* keyboard = - chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); + chromeos::input_method::ImeKeyboard* keyboard = + chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); + if (keyboard) keyboard->AddObserver(this); - } else { - ash::Shell::GetInstance()->PrependPreTargetHandler(this); - } } SigninScreenHandler::~SigninScreenHandler() { - if (base::SysInfo::IsRunningOnChromeOS()) { - chromeos::input_method::ImeKeyboard* keyboard = - chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); + chromeos::input_method::ImeKeyboard* keyboard = + chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); + if (keyboard) keyboard->RemoveObserver(this); - } else { - ash::Shell::GetInstance()->RemovePreTargetHandler(this); - } weak_factory_.InvalidateWeakPtrs(); if (delegate_) delegate_->SetWebUIHandler(NULL); @@ -839,11 +831,6 @@ void SigninScreenHandler::ShowSigninScreenForCreds( gaia_screen_handler_->ShowSigninScreenForCreds(username, password); } -void SigninScreenHandler::OnKeyEvent(ui::KeyEvent* key) { - if (key->type() == ui::ET_KEY_PRESSED && key->key_code() == ui::VKEY_CAPITAL) - OnCapsLockChanged(!caps_lock_enabled_); -} - void SigninScreenHandler::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index 4b079c61cd1075..cb7165e805bf5c 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h @@ -210,7 +210,6 @@ class SigninScreenHandler : public BaseScreenHandler, public LoginDisplayWebUIHandler, public content::NotificationObserver, - public ui::EventHandler, public ScreenlockBridge::LockHandler, public NetworkStateInformer::NetworkStateInformerObserver, public input_method::ImeKeyboard::Observer { @@ -301,9 +300,6 @@ class SigninScreenHandler bool animated, bool show_guest) OVERRIDE; - // ui::EventHandler implementation: - virtual void OnKeyEvent(ui::KeyEvent* key) OVERRIDE; - // content::NotificationObserver implementation: virtual void Observe(int type, const content::NotificationSource& source, diff --git a/chromeos/ime/fake_ime_keyboard.cc b/chromeos/ime/fake_ime_keyboard.cc index 4b8c71960f760f..d4bd0e0bb6f181 100644 --- a/chromeos/ime/fake_ime_keyboard.cc +++ b/chromeos/ime/fake_ime_keyboard.cc @@ -13,10 +13,15 @@ FakeImeKeyboard::FakeImeKeyboard() auto_repeat_is_enabled_(false) { } +FakeImeKeyboard::~FakeImeKeyboard() { +} + void FakeImeKeyboard::AddObserver(Observer* observer) { + observers_.AddObserver(observer); } void FakeImeKeyboard::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); } bool FakeImeKeyboard::SetCurrentKeyboardLayoutByName( @@ -37,7 +42,12 @@ void FakeImeKeyboard::DisableNumLock() { } void FakeImeKeyboard::SetCapsLockEnabled(bool enable_caps_lock) { + bool old_state = caps_lock_is_enabled_; caps_lock_is_enabled_ = enable_caps_lock; + if (old_state != enable_caps_lock) { + FOR_EACH_OBSERVER(ImeKeyboard::Observer, observers_, + OnCapsLockChanged(enable_caps_lock)); + } } bool FakeImeKeyboard::CapsLockIsEnabled() { diff --git a/chromeos/ime/fake_ime_keyboard.h b/chromeos/ime/fake_ime_keyboard.h index f710d61730aa94..131db0cd28923f 100644 --- a/chromeos/ime/fake_ime_keyboard.h +++ b/chromeos/ime/fake_ime_keyboard.h @@ -10,6 +10,7 @@ #include #include "base/compiler_specific.h" +#include "base/observer_list.h" #include "chromeos/chromeos_export.h" namespace chromeos { @@ -18,7 +19,7 @@ namespace input_method { class CHROMEOS_EXPORT FakeImeKeyboard : public ImeKeyboard { public: FakeImeKeyboard(); - virtual ~FakeImeKeyboard() {} + virtual ~FakeImeKeyboard(); virtual void AddObserver(Observer* observer) OVERRIDE; virtual void RemoveObserver(Observer* observer) OVERRIDE; @@ -42,6 +43,8 @@ class CHROMEOS_EXPORT FakeImeKeyboard : public ImeKeyboard { // TODO(yusukes): Add more variables for counting the numbers of the API calls private: + ObserverList observers_; + DISALLOW_COPY_AND_ASSIGN(FakeImeKeyboard); }; diff --git a/chromeos/ime/ime_keyboard_x11_unittest.cc b/chromeos/ime/ime_keyboard_x11_unittest.cc index cbf7cc7d303333..187bd8b20e7e56 100644 --- a/chromeos/ime/ime_keyboard_x11_unittest.cc +++ b/chromeos/ime/ime_keyboard_x11_unittest.cc @@ -21,22 +21,35 @@ namespace input_method { namespace { -class ImeKeyboardTest : public testing::Test { +class ImeKeyboardTest : public testing::Test, + public ImeKeyboard::Observer { public: ImeKeyboardTest() { } virtual void SetUp() { xkey_.reset(ImeKeyboard::Create()); + xkey_->AddObserver(this); + caps_changed_ = false; } virtual void TearDown() { + xkey_->RemoveObserver(this); xkey_.reset(); } - scoped_ptr xkey_; + virtual void OnCapsLockChanged(bool enabled) OVERRIDE { + caps_changed_ = true; + } + + void VerifyCapsLockChanged(bool changed) { + EXPECT_EQ(changed, caps_changed_); + caps_changed_ = false; + } + scoped_ptr xkey_; base::MessageLoopForUI message_loop_; + bool caps_changed_; }; // Returns true if X display is available. @@ -83,12 +96,23 @@ TEST_F(ImeKeyboardTest, TestSetCapsLockEnabled) { const bool initial_lock_state = xkey_->CapsLockIsEnabled(); xkey_->SetCapsLockEnabled(true); EXPECT_TRUE(xkey_->CapsLockIsEnabled()); + xkey_->SetCapsLockEnabled(false); EXPECT_FALSE(xkey_->CapsLockIsEnabled()); + VerifyCapsLockChanged(true); + xkey_->SetCapsLockEnabled(true); EXPECT_TRUE(xkey_->CapsLockIsEnabled()); + VerifyCapsLockChanged(true); + + xkey_->SetCapsLockEnabled(false); + EXPECT_FALSE(xkey_->CapsLockIsEnabled()); + VerifyCapsLockChanged(true); + xkey_->SetCapsLockEnabled(false); EXPECT_FALSE(xkey_->CapsLockIsEnabled()); + VerifyCapsLockChanged(false); + xkey_->SetCapsLockEnabled(initial_lock_state); } diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index 091b3fd566e9b1..799b3a352c132d 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc @@ -15,8 +15,11 @@ #include "base/logging.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/sys_info.h" #include "base/third_party/icu/icu_utf.h" #include "chromeos/ime/composition_text.h" +#include "chromeos/ime/ime_keyboard.h" +#include "chromeos/ime/input_method_manager.h" #include "ui/base/ime/text_input_client.h" #include "ui/events/event.h" #include "ui/gfx/rect.h" @@ -98,6 +101,23 @@ bool InputMethodChromeOS::DispatchKeyEvent(const ui::KeyEvent& event) { DCHECK(event.type() == ET_KEY_PRESSED || event.type() == ET_KEY_RELEASED); DCHECK(system_toplevel_window_focused()); + // For linux_chromeos, the ime keyboard cannot track the caps lock state by + // itself, so need to call SetCapsLockEnabled() method to reflect the caps + // lock state by the key event. + if (!base::SysInfo::IsRunningOnChromeOS()) { + chromeos::input_method::InputMethodManager* manager = + chromeos::input_method::InputMethodManager::Get(); + if (manager) { + chromeos::input_method::ImeKeyboard* keyboard = manager->GetImeKeyboard(); + if (keyboard && event.type() == ui::ET_KEY_PRESSED) { + bool caps = (event.key_code() == ui::VKEY_CAPITAL) + ? !keyboard->CapsLockIsEnabled() + : (event.flags() & EF_CAPS_LOCK_DOWN); + keyboard->SetCapsLockEnabled(caps); + } + } + } + // If |context_| is not usable, then we can only dispatch the key event as is. // We only dispatch the key event to input method when the |context_| is an // normal input field (not a password field).