diff options
author | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-10 22:03:45 +0000 |
---|---|---|
committer | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-10 22:03:45 +0000 |
commit | 3316496bdbe6f1120d6803190b50e70a85b232e5 (patch) | |
tree | 166e2611e1a9c61cbcf0fa1d228a33957df76d82 /chrome/browser/chromeos/input_method | |
parent | 260e1538389826b4e6bbda34d056aa2ebb2c8f13 (diff) | |
download | chromium_src-3316496bdbe6f1120d6803190b50e70a85b232e5.zip chromium_src-3316496bdbe6f1120d6803190b50e70a85b232e5.tar.gz chromium_src-3316496bdbe6f1120d6803190b50e70a85b232e5.tar.bz2 |
Extract a delegate interface from c/b/chromeos/input_method to permit decoupling from c/b.
BUG=164375
Review URL: https://chromiumcodereview.appspot.com/11415266
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172140 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/input_method')
18 files changed, 551 insertions, 467 deletions
diff --git a/chrome/browser/chromeos/input_method/browser_state_monitor.cc b/chrome/browser/chromeos/input_method/browser_state_monitor.cc index 0b2a8a2..c938d4a 100644 --- a/chrome/browser/chromeos/input_method/browser_state_monitor.cc +++ b/chrome/browser/chromeos/input_method/browser_state_monitor.cc @@ -4,32 +4,20 @@ #include "chrome/browser/chromeos/input_method/browser_state_monitor.h" -#include "chrome/browser/browser_process.h" +#include "base/logging.h" +#include "chrome/browser/chromeos/input_method/input_method_delegate.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" -#include "chrome/browser/chromeos/language_preferences.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/chrome_notification_types.h" -#include "chrome/common/pref_names.h" #include "content/public/browser/notification_service.h" namespace chromeos { namespace input_method { -namespace { -PrefService* GetPrefService() { - Profile* profile = ProfileManager::GetDefaultProfile(); - if (profile) - return profile->GetPrefs(); - return NULL; -} - -} // namespace - -BrowserStateMonitor::BrowserStateMonitor(InputMethodManager* manager) +BrowserStateMonitor::BrowserStateMonitor(InputMethodManager* manager, + InputMethodDelegate* delegate) : manager_(manager), - state_(InputMethodManager::STATE_LOGIN_SCREEN), - pref_service_(NULL) { + delegate_(delegate), + state_(InputMethodManager::STATE_LOGIN_SCREEN) { notification_registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_CHANGED, content::NotificationService::AllSources()); @@ -53,41 +41,6 @@ BrowserStateMonitor::~BrowserStateMonitor() { manager_->RemoveObserver(this); } -void BrowserStateMonitor::SetPrefServiceForTesting(PrefService* pref_service) { - pref_service_ = pref_service; -} - -void BrowserStateMonitor::UpdateLocalState( - const std::string& current_input_method) { - if (!g_browser_process || !g_browser_process->local_state()) - return; - g_browser_process->local_state()->SetString( - language_prefs::kPreferredKeyboardLayout, - current_input_method); -} - -void BrowserStateMonitor::UpdateUserPreferences( - const std::string& current_input_method) { - PrefService* pref_service = pref_service_ ? pref_service_ : GetPrefService(); - DCHECK(pref_service); - - // Even though we're DCHECK'ing to catch this on debug builds, we don't - // want to crash a release build in case the pref service is no longer - // available. - if (!pref_service) - return; - - const std::string current_input_method_on_pref = - pref_service->GetString(prefs::kLanguageCurrentInputMethod); - if (current_input_method_on_pref == current_input_method) - return; - - pref_service->SetString(prefs::kLanguagePreviousInputMethod, - current_input_method_on_pref); - pref_service->SetString(prefs::kLanguageCurrentInputMethod, - current_input_method); -} - void BrowserStateMonitor::InputMethodChanged(InputMethodManager* manager, bool show_message) { DCHECK_EQ(manager_, manager); @@ -101,10 +54,10 @@ void BrowserStateMonitor::InputMethodChanged(InputMethodManager* manager, << current_input_method; return; } - UpdateLocalState(current_input_method); + delegate_->SetSystemInputMethod(current_input_method); return; case InputMethodManager::STATE_BROWSER_SCREEN: - UpdateUserPreferences(current_input_method); + delegate_->SetUserInputMethod(current_input_method); return; case InputMethodManager::STATE_LOCK_SCREEN: // We use a special set of input methods on the screen. Do not update. diff --git a/chrome/browser/chromeos/input_method/browser_state_monitor.h b/chrome/browser/chromeos/input_method/browser_state_monitor.h index 5043de4..e74f8ca 100644 --- a/chrome/browser/chromeos/input_method/browser_state_monitor.h +++ b/chrome/browser/chromeos/input_method/browser_state_monitor.h @@ -7,38 +7,32 @@ #include <string> -#include "chrome/browser/api/prefs/pref_member.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" #include "chrome/browser/chromeos/input_method/input_method_manager.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_types.h" -class PrefService; - namespace chromeos { namespace input_method { +class InputMethodDelegate; + // A class which monitors a notification from the browser to keep track of the // browser state (not logged in, logged in, etc.) and notify the current state // to the input method manager. The class also updates the appropriate Chrome -// prefs (~/Local\ State or ~/Preferences) depending on the current browser -// state. +// prefs via the InputMethodDelegate, depending on the current browser state. class BrowserStateMonitor : public content::NotificationObserver, public InputMethodManager::Observer { public: - explicit BrowserStateMonitor(InputMethodManager* manager); + BrowserStateMonitor(InputMethodManager* manager, + InputMethodDelegate* delegate); virtual ~BrowserStateMonitor(); InputMethodManager::State state() const { return state_; } - void SetPrefServiceForTesting(PrefService* pref_service); - protected: - // Updates ~/Local\ State file. protected: for testing. - virtual void UpdateLocalState(const std::string& current_input_method); - // Updates ~/Preferences file. protected: for testing. - virtual void UpdateUserPreferences(const std::string& current_input_method); - // InputMethodManager::Observer overrides: virtual void InputMethodChanged(InputMethodManager* manager, bool show_message) OVERRIDE; @@ -51,17 +45,14 @@ class BrowserStateMonitor : public content::NotificationObserver, private: void SetState(InputMethodManager::State new_state); - void InitializePrefMembers(); InputMethodManager* manager_; + InputMethodDelegate* delegate_; InputMethodManager::State state_; // This is used to register this object to some browser notifications. content::NotificationRegistrar notification_registrar_; - // For testing. - PrefService* pref_service_; - DISALLOW_COPY_AND_ASSIGN(BrowserStateMonitor); }; diff --git a/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc b/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc index cebb82f..f439923 100644 --- a/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc +++ b/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc @@ -4,11 +4,12 @@ #include "chrome/browser/chromeos/input_method/browser_state_monitor.h" -#include "chrome/browser/api/prefs/pref_member.h" +#include <string> + +#include "base/basictypes.h" +#include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" #include "chrome/common/chrome_notification_types.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/testing_pref_service.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,74 +18,23 @@ namespace chromeos { namespace input_method { namespace { -void RegisterTestPrefs(PrefService* prefs) { - prefs->RegisterStringPref(prefs::kLanguagePreviousInputMethod, - "", - PrefService::UNSYNCABLE_PREF); - prefs->RegisterStringPref(prefs::kLanguageCurrentInputMethod, - "", - PrefService::UNSYNCABLE_PREF); -} - class TestableBrowserStateMonitor : public BrowserStateMonitor { public: using BrowserStateMonitor::InputMethodChanged; using BrowserStateMonitor::Observe; - explicit TestableBrowserStateMonitor(InputMethodManager* manager) - : BrowserStateMonitor(manager) { - ResetCounters(); - } - - virtual ~TestableBrowserStateMonitor() { - } - - void ResetCounters() { - update_local_state_count_ = 0; - last_local_state_.clear(); - update_user_pref_count_ = 0; - last_user_pref_.clear(); - } - - int update_local_state_count() const { return update_local_state_count_; } - const std::string& last_local_state() const { return last_local_state_; } - int update_user_pref_count() const { return update_user_pref_count_; } - const std::string& last_user_pref() const { return last_user_pref_; } - - protected: - virtual void UpdateLocalState( - const std::string& current_input_method) OVERRIDE { - ++update_local_state_count_; - last_local_state_ = current_input_method; - // Do not call the parent class' method since it depends on the global - // browser object which is a bit difficult to mock. This should be okay - // since the method is really simple. - } - - virtual void UpdateUserPreferences( - const std::string& current_input_method) OVERRIDE { - ++update_user_pref_count_; - last_user_pref_ = current_input_method; - BrowserStateMonitor::UpdateUserPreferences(current_input_method); + TestableBrowserStateMonitor(InputMethodManager* manager, + InputMethodDelegate* delegate) + : BrowserStateMonitor(manager, delegate) { } - - private: - int update_local_state_count_; - std::string last_local_state_; - int update_user_pref_count_; - std::string last_user_pref_; - - DISALLOW_COPY_AND_ASSIGN(TestableBrowserStateMonitor); }; } // anonymous namespace -TEST(BrowserStateMonitorTest, TestConstruction) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); +TEST(BrowserStateMonitorLifetimeTest, TestConstruction) { MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); + MockInputMethodDelegate mock_delegate; + TestableBrowserStateMonitor monitor(&mock_manager, &mock_delegate); // Check the initial state of the |mock_manager| and |monitor| objects. EXPECT_EQ(1, mock_manager.add_observer_count_); @@ -93,283 +43,235 @@ TEST(BrowserStateMonitorTest, TestConstruction) { EXPECT_EQ(InputMethodManager::STATE_LOGIN_SCREEN, monitor.state()); } -TEST(BrowserStateMonitorTest, TestDestruction) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); +TEST(BrowserStateMonitorLifetimeTest, TestDestruction) { MockInputMethodManager mock_manager; + MockInputMethodDelegate mock_delegate; { - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); + TestableBrowserStateMonitor monitor(&mock_manager, &mock_delegate); } EXPECT_EQ(1, mock_manager.remove_observer_count_); } -TEST(BrowserStateMonitorTest, TestObserveLoginUserChanged) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); +namespace { - EXPECT_EQ(1, mock_manager.set_state_count_); - monitor.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); +class BrowserStateMonitorTest : public testing::Test { + public: + BrowserStateMonitorTest() + : monitor_(&mock_manager_, &mock_delegate_) { + } - // Check if the state of the |mock_manager| as well as the |monitor| are both - // changed. - EXPECT_EQ(2, mock_manager.set_state_count_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, mock_manager.last_state_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); -} + protected: + MockInputMethodManager mock_manager_; + MockInputMethodDelegate mock_delegate_; + TestableBrowserStateMonitor monitor_; -TEST(BrowserStateMonitorTest, TestObserveSessionStarted) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); + private: + DISALLOW_COPY_AND_ASSIGN(BrowserStateMonitorTest); +}; - EXPECT_EQ(1, mock_manager.set_state_count_); - monitor.Observe(chrome::NOTIFICATION_SESSION_STARTED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); +} // anonymous namespace - // Check if the state of the |mock_manager| as well as the |monitor| are both +TEST_F(BrowserStateMonitorTest, TestObserveLoginUserChanged) { + EXPECT_EQ(1, mock_manager_.set_state_count_); + monitor_.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + + // Check if the state of the |mock_manager_| as well as the |monitor| are both // changed. - EXPECT_EQ(2, mock_manager.set_state_count_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, mock_manager.last_state_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); + EXPECT_EQ(2, mock_manager_.set_state_count_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, + mock_manager_.last_state_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); } -TEST(BrowserStateMonitorTest, TestObserveLoginUserChangedThenSessionStarted) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); +TEST_F(BrowserStateMonitorTest, TestObserveSessionStarted) { + EXPECT_EQ(1, mock_manager_.set_state_count_); + monitor_.Observe(chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); - EXPECT_EQ(1, mock_manager.set_state_count_); - monitor.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); + // Check if the state of the |mock_manager_| as well as the |monitor| are both + // changed. + EXPECT_EQ(2, mock_manager_.set_state_count_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, + mock_manager_.last_state_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); +} + +TEST_F(BrowserStateMonitorTest, TestObserveLoginUserChangedThenSessionStarted) { + EXPECT_EQ(1, mock_manager_.set_state_count_); + monitor_.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); - // Check if the state of the |mock_manager| as well as the |monitor| are both + // Check if the state of the |mock_manager_| as well as the |monitor| are both // changed. - EXPECT_EQ(2, mock_manager.set_state_count_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, mock_manager.last_state_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); + EXPECT_EQ(2, mock_manager_.set_state_count_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, + mock_manager_.last_state_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); - monitor.Observe(chrome::NOTIFICATION_SESSION_STARTED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); + monitor_.Observe(chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); // The second notification should be nop. - EXPECT_EQ(2, mock_manager.set_state_count_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, mock_manager.last_state_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); + EXPECT_EQ(2, mock_manager_.set_state_count_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, + mock_manager_.last_state_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); } -TEST(BrowserStateMonitorTest, TestObserveScreenLockUnlock) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); - - EXPECT_EQ(1, mock_manager.set_state_count_); - monitor.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); - EXPECT_EQ(2, mock_manager.set_state_count_); - monitor.Observe(chrome::NOTIFICATION_SESSION_STARTED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); - EXPECT_EQ(2, mock_manager.set_state_count_); +TEST_F(BrowserStateMonitorTest, TestObserveScreenLockUnlock) { + EXPECT_EQ(1, mock_manager_.set_state_count_); + monitor_.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + EXPECT_EQ(2, mock_manager_.set_state_count_); + monitor_.Observe(chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + EXPECT_EQ(2, mock_manager_.set_state_count_); bool locked = true; - monitor.Observe(chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, - content::NotificationService::AllSources(), - content::Details<bool>(&locked)); - EXPECT_EQ(3, mock_manager.set_state_count_); - EXPECT_EQ(InputMethodManager::STATE_LOCK_SCREEN, mock_manager.last_state_); - EXPECT_EQ(InputMethodManager::STATE_LOCK_SCREEN, monitor.state()); + monitor_.Observe(chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, + content::NotificationService::AllSources(), + content::Details<bool>(&locked)); + EXPECT_EQ(3, mock_manager_.set_state_count_); + EXPECT_EQ(InputMethodManager::STATE_LOCK_SCREEN, + mock_manager_.last_state_); + EXPECT_EQ(InputMethodManager::STATE_LOCK_SCREEN, monitor_.state()); // When the screen is locked, the monitor should ignore input method changes. - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(0, monitor.update_user_pref_count()); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(0, mock_delegate_.update_user_input_method_count()); locked = false; - monitor.Observe(chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, - content::NotificationService::AllSources(), - content::Details<bool>(&locked)); - EXPECT_EQ(4, mock_manager.set_state_count_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, mock_manager.last_state_); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); - - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(1, monitor.update_user_pref_count()); + monitor_.Observe(chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, + content::NotificationService::AllSources(), + content::Details<bool>(&locked)); + EXPECT_EQ(4, mock_manager_.set_state_count_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, + mock_manager_.last_state_); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); + + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(1, mock_delegate_.update_user_input_method_count()); } -TEST(BrowserStateMonitorTest, TestObserveAppTerminating) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); - - EXPECT_EQ(1, mock_manager.set_state_count_); - monitor.Observe(chrome::NOTIFICATION_APP_TERMINATING, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); +TEST_F(BrowserStateMonitorTest, TestObserveAppTerminating) { + EXPECT_EQ(1, mock_manager_.set_state_count_); + monitor_.Observe(chrome::NOTIFICATION_APP_TERMINATING, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); - // Check if the state of the |mock_manager| as well as the |monitor| are both + // Check if the state of the |mock_manager_| as well as the |monitor| are both // changed. - EXPECT_EQ(2, mock_manager.set_state_count_); + EXPECT_EQ(2, mock_manager_.set_state_count_); EXPECT_EQ(InputMethodManager::STATE_TERMINATING, - mock_manager.last_state_); - EXPECT_EQ(InputMethodManager::STATE_TERMINATING, monitor.state()); + mock_manager_.last_state_); + EXPECT_EQ(InputMethodManager::STATE_TERMINATING, monitor_.state()); // In the terminating state, the monitor should ignore input method changes. - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(0, monitor.update_user_pref_count()); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(0, mock_delegate_.update_user_input_method_count()); } -TEST(BrowserStateMonitorTest, TestUpdatePrefOnLoginScreen) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); - - EXPECT_EQ(InputMethodManager::STATE_LOGIN_SCREEN, monitor.state()); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(1, monitor.update_local_state_count()); - EXPECT_EQ(0, monitor.update_user_pref_count()); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(2, monitor.update_local_state_count()); - EXPECT_EQ(0, monitor.update_user_pref_count()); +TEST_F(BrowserStateMonitorTest, TestUpdatePrefOnLoginScreen) { + EXPECT_EQ(InputMethodManager::STATE_LOGIN_SCREEN, monitor_.state()); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(1, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(0, mock_delegate_.update_user_input_method_count()); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(2, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(0, mock_delegate_.update_user_input_method_count()); } -TEST(BrowserStateMonitorTest, TestUpdatePrefOnBrowserScreen) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); - - monitor.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); - - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(1, monitor.update_user_pref_count()); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(2, monitor.update_user_pref_count()); - - monitor.Observe(chrome::NOTIFICATION_SESSION_STARTED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); - - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(3, monitor.update_user_pref_count()); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(4, monitor.update_user_pref_count()); +TEST_F(BrowserStateMonitorTest, TestUpdatePrefOnBrowserScreen) { + monitor_.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); + + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(1, mock_delegate_.update_user_input_method_count()); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(2, mock_delegate_.update_user_input_method_count()); + + monitor_.Observe(chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); + + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(3, mock_delegate_.update_user_input_method_count()); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(4, mock_delegate_.update_user_input_method_count()); } -TEST(BrowserStateMonitorTest, TestUpdatePrefOnLoginScreenDetails) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); - - EXPECT_EQ(InputMethodManager::STATE_LOGIN_SCREEN, monitor.state()); +TEST_F(BrowserStateMonitorTest, TestUpdatePrefOnLoginScreenDetails) { + EXPECT_EQ(InputMethodManager::STATE_LOGIN_SCREEN, monitor_.state()); std::string input_method_id = "xkb:us:dvorak:eng"; - mock_manager.SetCurrentInputMethodId(input_method_id); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(1, monitor.update_local_state_count()); - EXPECT_EQ(0, monitor.update_user_pref_count()); - EXPECT_EQ(input_method_id, monitor.last_local_state()); + mock_manager_.SetCurrentInputMethodId(input_method_id); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(1, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(0, mock_delegate_.update_user_input_method_count()); + EXPECT_EQ(input_method_id, mock_delegate_.system_input_method()); input_method_id = "xkb:us:colemak:eng"; - mock_manager.SetCurrentInputMethodId(input_method_id); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(2, monitor.update_local_state_count()); - EXPECT_EQ(0, monitor.update_user_pref_count()); - EXPECT_EQ(input_method_id, monitor.last_local_state()); + mock_manager_.SetCurrentInputMethodId(input_method_id); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(2, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(0, mock_delegate_.update_user_input_method_count()); + EXPECT_EQ(input_method_id, mock_delegate_.system_input_method()); } -TEST(BrowserStateMonitorTest, TestUpdatePrefOnBrowserScreenDetails) { - TestingPrefService prefs; - RegisterTestPrefs(&prefs); - MockInputMethodManager mock_manager; - TestableBrowserStateMonitor monitor(&mock_manager); - monitor.SetPrefServiceForTesting(&prefs); - - StringPrefMember previous; - previous.Init(prefs::kLanguagePreviousInputMethod, &prefs); - EXPECT_EQ("", previous.GetValue()); - StringPrefMember current; - current.Init(prefs::kLanguageCurrentInputMethod, &prefs); - EXPECT_EQ("", current.GetValue()); - - monitor.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); - monitor.Observe(chrome::NOTIFICATION_SESSION_STARTED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); - EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor.state()); +TEST_F(BrowserStateMonitorTest, TestUpdatePrefOnBrowserScreenDetails) { + monitor_.Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); + monitor_.Observe(chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + EXPECT_EQ(InputMethodManager::STATE_BROWSER_SCREEN, monitor_.state()); const std::string input_method_id = "xkb:us:dvorak:eng"; - mock_manager.SetCurrentInputMethodId(input_method_id); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(1, monitor.update_user_pref_count()); - EXPECT_EQ(input_method_id, monitor.last_user_pref()); - EXPECT_EQ("", previous.GetValue()); - EXPECT_EQ(input_method_id, current.GetValue()); - - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(2, monitor.update_user_pref_count()); - EXPECT_EQ(input_method_id, monitor.last_user_pref()); - EXPECT_EQ("", previous.GetValue()); - EXPECT_EQ(input_method_id, current.GetValue()); + mock_manager_.SetCurrentInputMethodId(input_method_id); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(1, mock_delegate_.update_user_input_method_count()); + EXPECT_EQ(input_method_id, mock_delegate_.user_input_method()); + + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(2, mock_delegate_.update_user_input_method_count()); + EXPECT_EQ(input_method_id, mock_delegate_.user_input_method()); const std::string input_method_id_2 = "xkb:us:colemak:eng"; - mock_manager.SetCurrentInputMethodId(input_method_id_2); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(3, monitor.update_user_pref_count()); - EXPECT_EQ(input_method_id_2, monitor.last_user_pref()); - EXPECT_EQ(input_method_id, previous.GetValue()); - EXPECT_EQ(input_method_id_2, current.GetValue()); + mock_manager_.SetCurrentInputMethodId(input_method_id_2); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(3, mock_delegate_.update_user_input_method_count()); + EXPECT_EQ(input_method_id_2, mock_delegate_.user_input_method()); const std::string input_method_id_3 = "xkb:us::eng"; - mock_manager.SetCurrentInputMethodId(input_method_id_3); - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(4, monitor.update_user_pref_count()); - EXPECT_EQ(input_method_id_3, monitor.last_user_pref()); - EXPECT_EQ(input_method_id_2, previous.GetValue()); - EXPECT_EQ(input_method_id_3, current.GetValue()); - - monitor.InputMethodChanged(&mock_manager, false); - EXPECT_EQ(0, monitor.update_local_state_count()); - EXPECT_EQ(5, monitor.update_user_pref_count()); - EXPECT_EQ(input_method_id_3, monitor.last_user_pref()); - EXPECT_EQ(input_method_id_2, previous.GetValue()); - EXPECT_EQ(input_method_id_3, current.GetValue()); + mock_manager_.SetCurrentInputMethodId(input_method_id_3); + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(4, mock_delegate_.update_user_input_method_count()); + EXPECT_EQ(input_method_id_3, mock_delegate_.user_input_method()); + + monitor_.InputMethodChanged(&mock_manager_, false); + EXPECT_EQ(0, mock_delegate_.update_system_input_method_count()); + EXPECT_EQ(5, mock_delegate_.update_user_input_method_count()); + EXPECT_EQ(input_method_id_3, mock_delegate_.user_input_method()); } } // namespace input_method diff --git a/chrome/browser/chromeos/input_method/input_method_delegate.h b/chrome/browser/chromeos/input_method/input_method_delegate.h new file mode 100644 index 0000000..4117ad3 --- /dev/null +++ b/chrome/browser/chromeos/input_method/input_method_delegate.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 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_INPUT_METHOD_INPUT_METHOD_DELEGATE_H_ +#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_DELEGATE_H_ + +#include <string> + +#include "base/basictypes.h" + +namespace chromeos { +namespace input_method { + +// Provides access to read/persist Input Method-related properties. +class InputMethodDelegate { + public: + InputMethodDelegate() {} + virtual ~InputMethodDelegate() {} + + // Persists input method choices when no user is logged in. + virtual void SetSystemInputMethod(const std::string& input_method) = 0; + // Persists input method choices when the user is logged in. + virtual void SetUserInputMethod(const std::string& input_method) = 0; + // Retrieves the hardware keyboard layout ID. May return an empty string if + // the ID is unknown. + virtual std::string GetHardwareKeyboardLayout() const = 0; + // Retrieves the currently active UI locale. + virtual std::string GetActiveLocale() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(InputMethodDelegate); +}; + +} // namespace input_method +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_DELEGATE_H_ diff --git a/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc b/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc new file mode 100644 index 0000000..4b6e71f --- /dev/null +++ b/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc @@ -0,0 +1,73 @@ +// Copyright (c) 2012 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/input_method/input_method_delegate_impl.h" + +#include "base/prefs/public/pref_service_base.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/language_preferences.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/pref_names.h" + +namespace chromeos { +namespace input_method { + +InputMethodDelegateImpl::InputMethodDelegateImpl() {} + +void InputMethodDelegateImpl::SetSystemInputMethod( + const std::string& input_method) { + if (g_browser_process) { + PrefServiceBase* local_state = g_browser_process->local_state(); + if (local_state) { + local_state->SetString(language_prefs::kPreferredKeyboardLayout, + input_method); + return; + } + } + + NOTREACHED(); +} + +void InputMethodDelegateImpl::SetUserInputMethod( + const std::string& input_method) { + PrefServiceBase* user_prefs = NULL; + Profile* profile = ProfileManager::GetDefaultProfile(); + if (profile) + user_prefs = profile->GetPrefs(); + if (!user_prefs) + return; + + const std::string current_input_method_on_pref = + user_prefs->GetString(prefs::kLanguageCurrentInputMethod); + if (current_input_method_on_pref == input_method) + return; + + user_prefs->SetString(prefs::kLanguagePreviousInputMethod, + current_input_method_on_pref); + user_prefs->SetString(prefs::kLanguageCurrentInputMethod, + input_method); +} + +std::string InputMethodDelegateImpl::GetHardwareKeyboardLayout() const { + if (g_browser_process) { + PrefServiceBase* local_state = g_browser_process->local_state(); + if (local_state) + return local_state->GetString(prefs::kHardwareKeyboardLayout); + } + // This shouldn't happen but just in case. + DVLOG(1) << "Local state is not yet ready."; + return std::string(); +} + +std::string InputMethodDelegateImpl::GetActiveLocale() const { + if (g_browser_process) + return g_browser_process->GetApplicationLocale(); + + NOTREACHED(); + return std::string(); +} + +} // namespace input_method +} // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/input_method_delegate_impl.h b/chrome/browser/chromeos/input_method/input_method_delegate_impl.h new file mode 100644 index 0000000..6aea2ae --- /dev/null +++ b/chrome/browser/chromeos/input_method/input_method_delegate_impl.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 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_INPUT_METHOD_INPUT_METHOD_DELEGATE_IMPL_H_ +#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_DELEGATE_IMPL_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chrome/browser/chromeos/input_method/input_method_delegate.h" + +namespace chromeos { +namespace input_method { + +// Persists input method changes to the BrowserProcess local state or to the +// user preferences, as appropriate. Accesses the hardware keyboard layout and +// application locale from the BrowserProcess. +class InputMethodDelegateImpl : public InputMethodDelegate { + public: + InputMethodDelegateImpl(); + + // InputMethodDelegate implementation. + virtual void SetSystemInputMethod( + const std::string& input_method) OVERRIDE; + virtual void SetUserInputMethod(const std::string& input_method) OVERRIDE; + virtual std::string GetHardwareKeyboardLayout() const OVERRIDE; + virtual std::string GetActiveLocale() const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(InputMethodDelegateImpl); +}; + +} // namespace input_method +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_DELEGATE_IMPL_H_ diff --git a/chrome/browser/chromeos/input_method/input_method_manager.cc b/chrome/browser/chromeos/input_method/input_method_manager.cc index 1afd413..1abf167 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager.cc @@ -4,6 +4,7 @@ #include "chrome/browser/chromeos/input_method/input_method_manager.h" +#include "chrome/browser/chromeos/input_method/input_method_delegate_impl.h" #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" namespace chromeos { @@ -16,7 +17,8 @@ InputMethodManager* g_input_method_manager = NULL; // static void InputMethodManager::Initialize() { DCHECK(!g_input_method_manager); - InputMethodManagerImpl* impl = new InputMethodManagerImpl; + InputMethodManagerImpl* impl = new InputMethodManagerImpl( + scoped_ptr<InputMethodDelegate>(new InputMethodDelegateImpl)); impl->Init(); g_input_method_manager = impl; DVLOG(1) << "InputMethodManager initialized"; diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc index a72b127..8a45e83 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc @@ -12,6 +12,7 @@ #include "base/stringprintf.h" #include "chrome/browser/chromeos/input_method/browser_state_monitor.h" #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" +#include "chrome/browser/chromeos/input_method/input_method_delegate.h" #include "chrome/browser/chromeos/input_method/input_method_engine_ibus.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/xkeyboard.h" @@ -32,9 +33,11 @@ bool Contains(const std::vector<std::string>& container, } // namespace -InputMethodManagerImpl::InputMethodManagerImpl() - : state_(STATE_LOGIN_SCREEN), - util_(GetSupportedInputMethods()) { +InputMethodManagerImpl::InputMethodManagerImpl( + scoped_ptr<InputMethodDelegate> delegate) + : delegate_(delegate.Pass()), + state_(STATE_LOGIN_SCREEN), + util_(delegate_.get(), GetSupportedInputMethods()) { } InputMethodManagerImpl::~InputMethodManagerImpl() { @@ -579,7 +582,7 @@ void InputMethodManagerImpl::OnDisconnected() { void InputMethodManagerImpl::Init() { DCHECK(!ibus_controller_.get()); - browser_state_monitor_.reset(new BrowserStateMonitor(this)); + browser_state_monitor_.reset(new BrowserStateMonitor(this, delegate_.get())); ibus_controller_.reset(IBusController::Create()); xkeyboard_.reset(XKeyboard::Create(util_)); ibus_controller_->AddObserver(this); @@ -682,10 +685,5 @@ void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { DVLOG(1) << "Failed to initialize the candidate window controller"; } -// static -InputMethodManagerImpl* InputMethodManagerImpl::GetInstanceForTesting() { - return new InputMethodManagerImpl; -} - } // namespace input_method } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.h b/chrome/browser/chromeos/input_method/input_method_manager_impl.h index 7014ef74..49f4dde 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h @@ -22,12 +22,14 @@ namespace chromeos { class InputMethodEngineIBus; namespace input_method { +class InputMethodDelegate; // The implementation of InputMethodManager. class InputMethodManagerImpl : public InputMethodManager, public CandidateWindowController::Observer, public IBusController::Observer { public: + explicit InputMethodManagerImpl(scoped_ptr<InputMethodDelegate> delegate); virtual ~InputMethodManagerImpl(); // InputMethodManager override: @@ -80,14 +82,8 @@ class InputMethodManagerImpl : public InputMethodManager, // Sets |xkeyboard_|. void SetXKeyboardForTesting(XKeyboard* xkeyboard); - // Creates a new instance of this class. The caller has to delete the returned - // object. The caller also have to set a mock CandidateWindowController, - // IBusController, and XKeyboard. See the setters above. - static InputMethodManagerImpl* GetInstanceForTesting(); - private: friend class InputMethodManager; - InputMethodManagerImpl(); // IBusController overrides: virtual void PropertyChanged() OVERRIDE; @@ -135,6 +131,8 @@ class InputMethodManagerImpl : public InputMethodManager, void ChangeInputMethodInternal(const std::string& input_method_id, bool show_message); + scoped_ptr<InputMethodDelegate> delegate_; + // The current browser status. State state_; diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc index d3de2e0..c2eea79 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc @@ -6,10 +6,13 @@ #include <algorithm> +#include "base/basictypes.h" +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/chromeos/input_method/mock_candidate_window_controller.h" #include "chrome/browser/chromeos/input_method/mock_ibus_controller.h" +#include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" #include "chrome/browser/chromeos/input_method/mock_xkeyboard.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/accelerators/accelerator.h" @@ -25,13 +28,17 @@ namespace { class InputMethodManagerImplTest : public testing::Test { public: InputMethodManagerImplTest() - : controller_(NULL), - candidate_window_controller_(NULL) { + : delegate_(NULL), + controller_(NULL), + candidate_window_controller_(NULL), + xkeyboard_(NULL) { } virtual ~InputMethodManagerImplTest() {} - virtual void SetUp() { - manager_.reset(InputMethodManagerImpl::GetInstanceForTesting()); + virtual void SetUp() OVERRIDE { + delegate_ = new MockInputMethodDelegate(); + manager_.reset(new InputMethodManagerImpl( + scoped_ptr<InputMethodDelegate>(delegate_))); controller_ = new MockIBusController; manager_->SetIBusControllerForTesting(controller_); candidate_window_controller_ = new MockCandidateWindowController; @@ -41,20 +48,17 @@ class InputMethodManagerImplTest : public testing::Test { manager_->SetXKeyboardForTesting(xkeyboard_); } - virtual void TearDown() { - manager_.reset(); + virtual void TearDown() OVERRIDE { + delegate_ = NULL; controller_ = NULL; candidate_window_controller_ = NULL; xkeyboard_ = NULL; - } - - void SetHardwareKeyboardLayout(const std::string& input_method_id) { - manager_->GetInputMethodUtil()->SetHardwareInputMethodIdForTesting( - input_method_id); + manager_.reset(); } protected: scoped_ptr<InputMethodManagerImpl> manager_; + MockInputMethodDelegate* delegate_; MockIBusController* controller_; MockCandidateWindowController* candidate_window_controller_; MockXKeyboard* xkeyboard_; @@ -120,11 +124,6 @@ TEST_F(InputMethodManagerImplTest, TestGetXKeyboard) { EXPECT_EQ(xkeyboard_, manager_->GetXKeyboard()); } -TEST_F(InputMethodManagerImplTest, TestGetInputMethodUtil) { - EXPECT_TRUE(manager_->GetInputMethodUtil()); - SetHardwareKeyboardLayout("xkb:fr::fra"); // check this does not crash. -} - TEST_F(InputMethodManagerImplTest, TestCandidateWindowObserver) { TestCandidateWindowObserver observer; candidate_window_controller_->NotifyCandidateWindowOpened(); // nop @@ -221,11 +220,11 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayouts) { TEST_F(InputMethodManagerImplTest, TestEnableLayoutsNonUsHardwareKeyboard) { // The physical layout is French. - SetHardwareKeyboardLayout("xkb:fr::fra"); + delegate_->set_hardware_keyboard_layout("xkb:fr::fra"); manager_->EnableLayouts("en-US", ""); EXPECT_EQ(6U, manager_->GetNumActiveInputMethods()); // 5 + French // The physical layout is Japanese. - SetHardwareKeyboardLayout("xkb:jp::jpn"); + delegate_->set_hardware_keyboard_layout("xkb:jp::jpn"); manager_->EnableLayouts("ja", ""); // "xkb:us::eng" is not needed, hence 1. EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); diff --git a/chrome/browser/chromeos/input_method/input_method_util.cc b/chrome/browser/chromeos/input_method/input_method_util.cc index 4a5ae06..dcc0732 100644 --- a/chrome/browser/chromeos/input_method/input_method_util.cc +++ b/chrome/browser/chromeos/input_method/input_method_util.cc @@ -11,12 +11,11 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/prefs/public/pref_service_base.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/common/pref_names.h" +#include "chrome/browser/chromeos/input_method/input_method_delegate.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_collator.h" @@ -82,13 +81,7 @@ const struct { const size_t kMappingImeIdToMediumLenNameResourceIdLen = ARRAYSIZE_UNSAFE(kMappingImeIdToMediumLenNameResourceId); -string16 GetLanguageName(const std::string& language_code) { - const string16 language_name = l10n_util::GetDisplayNameForLocale( - language_code, g_browser_process->GetApplicationLocale(), true); - return language_name; -} - -} +} // namespace namespace chromeos { @@ -267,20 +260,22 @@ const size_t kEnglishToResourceIdArraySize = // corresponding language names, using the ICU collator. struct CompareLanguageCodesByLanguageName : std::binary_function<const std::string&, const std::string&, bool> { - explicit CompareLanguageCodesByLanguageName(icu::Collator* collator) - : collator_(collator) { + CompareLanguageCodesByLanguageName(InputMethodUtil* util, + icu::Collator* collator) + : util_(util), collator_(collator) { } // Calling GetLanguageDisplayNameFromCode() in the comparator is not // efficient, but acceptable as the function is cheap, and the language // list is short (about 60 at most). bool operator()(const std::string& s1, const std::string& s2) const { - const string16 key1 = InputMethodUtil::GetLanguageDisplayNameFromCode(s1); - const string16 key2 = InputMethodUtil::GetLanguageDisplayNameFromCode(s2); + const string16 key1 = util_->GetLanguageDisplayNameFromCode(s1); + const string16 key2 = util_->GetLanguageDisplayNameFromCode(s2); return l10n_util::StringComparator<string16>(collator_)(key1, key2); } private: + InputMethodUtil* util_; icu::Collator* collator_; }; @@ -306,8 +301,10 @@ const ExtraLanguage kExtraLanguages[] = { const size_t kExtraLanguagesLength = arraysize(kExtraLanguages); InputMethodUtil::InputMethodUtil( + InputMethodDelegate* delegate, scoped_ptr<InputMethodDescriptors> supported_input_methods) - : supported_input_methods_(supported_input_methods.Pass()) { + : supported_input_methods_(supported_input_methods.Pass()), + delegate_(delegate) { ReloadInternalMaps(); // Initialize a map from English string to Chrome string resource ID as well. @@ -484,7 +481,10 @@ string16 InputMethodUtil::GetInputMethodLongName( language_code == "de" || language_code == "fr" || language_code == "nl") { - text = GetLanguageName(language_code) + UTF8ToUTF16(" - ") + text; + const string16 language_name = l10n_util::GetDisplayNameForLocale( + language_code, delegate_->GetActiveLocale(), true); + + text = language_name + UTF8ToUTF16(" - ") + text; } DCHECK(!text.empty()); @@ -508,11 +508,8 @@ const InputMethodDescriptor* InputMethodUtil::GetInputMethodDescriptorFromXkbId( // static string16 InputMethodUtil::GetLanguageDisplayNameFromCode( const std::string& language_code) { - if (!g_browser_process) { - return string16(); - } return l10n_util::GetDisplayNameForLocale( - language_code, g_browser_process->GetApplicationLocale(), true); + language_code, delegate_->GetActiveLocale(), true); } // static @@ -521,23 +518,19 @@ string16 InputMethodUtil::GetLanguageNativeDisplayNameFromCode( return l10n_util::GetDisplayNameForLocale(language_code, language_code, true); } -// static void InputMethodUtil::SortLanguageCodesByNames( std::vector<std::string>* language_codes) { - if (!g_browser_process) { - return; - } // We should build collator outside of the comparator. We cannot have // scoped_ptr<> in the comparator for a subtle STL reason. UErrorCode error = U_ZERO_ERROR; - icu::Locale locale(g_browser_process->GetApplicationLocale().c_str()); + icu::Locale locale(delegate_->GetActiveLocale().c_str()); scoped_ptr<icu::Collator> collator( icu::Collator::createInstance(locale, error)); if (U_FAILURE(error)) { collator.reset(); } std::sort(language_codes->begin(), language_codes->end(), - CompareLanguageCodesByLanguageName(collator.get())); + CompareLanguageCodesByLanguageName(this, collator.get())); } bool InputMethodUtil::GetInputMethodIdsFromLanguageCode( @@ -647,27 +640,8 @@ void InputMethodUtil::GetLanguageCodesFromInputMethodIds( } std::string InputMethodUtil::GetHardwareInputMethodId() const { - if (!hardware_input_method_id_for_testing_.empty()) { - return hardware_input_method_id_for_testing_; - } + const std::string input_method_id = delegate_->GetHardwareKeyboardLayout(); - if (!(g_browser_process && g_browser_process->local_state())) { - // This shouldn't happen but just in case. - DVLOG(1) << "Local state is not yet ready"; - return InputMethodDescriptor::GetFallbackInputMethodDescriptor().id(); - } - - PrefService* local_state = g_browser_process->local_state(); - if (!local_state->FindPreference(prefs::kHardwareKeyboardLayout)) { - // This could happen in unittests. We register the preference in - // BrowserMain::InitializeLocalState and that method is not called during - // unittests. - DVLOG(1) << prefs::kHardwareKeyboardLayout << " is not registered"; - return InputMethodDescriptor::GetFallbackInputMethodDescriptor().id(); - } - - const std::string input_method_id = - local_state->GetString(prefs::kHardwareKeyboardLayout); if (input_method_id.empty()) { // This is totally fine if it's empty. The hardware keyboard layout is // not stored if startup_manifest.json (OEM customization data) is not @@ -726,10 +700,5 @@ void InputMethodUtil::OnLocaleChanged() { ReloadInternalMaps(); } -void InputMethodUtil::SetHardwareInputMethodIdForTesting( - const std::string& input_method_id) { - hardware_input_method_id_for_testing_ = input_method_id; -} - } // namespace input_method } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/input_method_util.h b/chrome/browser/chromeos/input_method/input_method_util.h index 69c1fa3..cd2f6ed 100644 --- a/chrome/browser/chromeos/input_method/input_method_util.h +++ b/chrome/browser/chromeos/input_method/input_method_util.h @@ -18,6 +18,8 @@ namespace chromeos { namespace input_method { +class InputMethodDelegate; + // The list of language that do not have associated input methods in IBus. // For these languages, we associate input methods here. struct ExtraLanguage { @@ -38,8 +40,8 @@ class InputMethodUtil { // |supported_input_methods| is a list of all input methods supported, // including ones not active. The list is used to initialize member variables // in this class. - explicit InputMethodUtil( - scoped_ptr<InputMethodDescriptors> supported_input_methods); + InputMethodUtil(InputMethodDelegate* delegate, + scoped_ptr<InputMethodDescriptors> supported_input_methods); ~InputMethodUtil(); // Converts a string sent from IBus IME engines, which is written in English, @@ -129,9 +131,6 @@ class InputMethodUtil { // changed, so that the internal maps of this library is reloaded. void OnLocaleChanged(); - // Sets an input method ID of the hardware keyboard for testing. - void SetHardwareInputMethodIdForTesting(const std::string& input_method_id); - // Returns true if the given input method id is supported. bool IsValidInputMethodId(const std::string& input_method_id) const; @@ -146,7 +145,7 @@ class InputMethodUtil { // internally. // Examples: "fi" => "Finnish" // "en-US" => "English (United States)" - static string16 GetLanguageDisplayNameFromCode( + string16 GetLanguageDisplayNameFromCode( const std::string& language_code); // Converts a language code to a language native display name. @@ -175,7 +174,7 @@ class InputMethodUtil { // Sorts the given language codes by their corresponding language names, using // the unicode string comparator. Uses unstable sorting. protected: for unit // testing as well. - static void SortLanguageCodesByNames( + void SortLanguageCodesByNames( std::vector<std::string>* language_codes); // All input methods that are supported, including ones not active. @@ -202,7 +201,9 @@ class InputMethodUtil { typedef base::hash_map<std::string, int> HashType; HashType english_to_resource_id_; - std::string hardware_input_method_id_for_testing_; + InputMethodDelegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(InputMethodUtil); }; } // namespace input_method diff --git a/chrome/browser/chromeos/input_method/input_method_util_unittest.cc b/chrome/browser/chromeos/input_method/input_method_util_unittest.cc index 3a44888..7b5821a 100644 --- a/chrome/browser/chromeos/input_method/input_method_util_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_util_unittest.cc @@ -10,6 +10,7 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/chromeos/input_method/input_method_manager.h" #include "chrome/browser/chromeos/input_method/input_method_whitelist.h" +#include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" #include "grit/generated_resources.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" @@ -24,8 +25,9 @@ namespace { class TestableInputMethodUtil : public InputMethodUtil { public: - explicit TestableInputMethodUtil(scoped_ptr<InputMethodDescriptors> methods) - : InputMethodUtil(methods.Pass()) { + explicit TestableInputMethodUtil(InputMethodDelegate* delegate, + scoped_ptr<InputMethodDescriptors> methods) + : InputMethodUtil(delegate, methods.Pass()) { } // Change access rights. using InputMethodUtil::StringIsSupported; @@ -39,7 +41,8 @@ class TestableInputMethodUtil : public InputMethodUtil { class InputMethodUtilTest : public testing::Test { public: - InputMethodUtilTest() : util_(whitelist_.GetSupportedInputMethods()) { + InputMethodUtilTest() + : util_(&delegate_, whitelist_.GetSupportedInputMethods()) { } InputMethodDescriptor GetDesc(const std::string& id, @@ -52,6 +55,7 @@ class InputMethodUtilTest : public testing::Test { false); } + MockInputMethodDelegate delegate_; InputMethodWhitelist whitelist_; TestableInputMethodUtil util_; }; @@ -373,13 +377,13 @@ TEST_F(InputMethodUtilTest, TestGetLanguageNativeDisplayNameFromCode) { TEST_F(InputMethodUtilTest, TestSortLanguageCodesByNames) { std::vector<std::string> language_codes; // Check if this function can handle an empty list. - TestableInputMethodUtil::SortLanguageCodesByNames(&language_codes); + util_.SortLanguageCodesByNames(&language_codes); language_codes.push_back("ja"); language_codes.push_back("fr"); // For "t", see the comment in NormalizeLanguageCode test. language_codes.push_back("t"); - TestableInputMethodUtil::SortLanguageCodesByNames(&language_codes); + util_.SortLanguageCodesByNames(&language_codes); ASSERT_EQ(3U, language_codes.size()); ASSERT_EQ("fr", language_codes[0]); // French ASSERT_EQ("ja", language_codes[1]); // Japanese @@ -387,7 +391,7 @@ TEST_F(InputMethodUtilTest, TestSortLanguageCodesByNames) { // Add a duplicate entry and see if it works. language_codes.push_back("ja"); - TestableInputMethodUtil::SortLanguageCodesByNames(&language_codes); + util_.SortLanguageCodesByNames(&language_codes); ASSERT_EQ(4U, language_codes.size()); ASSERT_EQ("fr", language_codes[0]); // French ASSERT_EQ("ja", language_codes[1]); // Japanese @@ -536,13 +540,6 @@ TEST_F(InputMethodUtilTest, TestGetLanguageCodesFromInputMethodIds) { EXPECT_EQ("fr", language_codes[2]); } -TEST_F(InputMethodUtilTest, TestSetHardwareInputMethodId) { - util_.SetHardwareInputMethodIdForTesting("xkb:fr::fra"); - EXPECT_EQ("xkb:fr::fra", util_.GetHardwareInputMethodId()); - // Reset to the default behavior just in case. - util_.SetHardwareInputMethodIdForTesting(""); -} - // Test all supported descriptors to detect a typo in ibus_input_methods.txt. TEST_F(InputMethodUtilTest, TestIBusInputMethodText) { for (size_t i = 0; i < util_.supported_input_methods_->size(); ++i) { diff --git a/chrome/browser/chromeos/input_method/mock_input_method_delegate.cc b/chrome/browser/chromeos/input_method/mock_input_method_delegate.cc new file mode 100644 index 0000000..62111e66 --- /dev/null +++ b/chrome/browser/chromeos/input_method/mock_input_method_delegate.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2012 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/input_method/mock_input_method_delegate.h" + +namespace chromeos { +namespace input_method { + +MockInputMethodDelegate::MockInputMethodDelegate() + : active_locale_("en"), + update_system_input_method_count_(0), + update_user_input_method_count_(0) { +} + +MockInputMethodDelegate::~MockInputMethodDelegate() { +} + +void MockInputMethodDelegate::SetSystemInputMethod( + const std::string& input_method) { + ++update_system_input_method_count_; + system_input_method_ = input_method; +} + +void MockInputMethodDelegate::SetUserInputMethod( + const std::string& input_method) { + ++update_user_input_method_count_; + user_input_method_ = input_method; +} + +std::string MockInputMethodDelegate::GetHardwareKeyboardLayout() const { + return hardware_keyboard_layout_; +} + +std::string MockInputMethodDelegate::GetActiveLocale() const { + return active_locale_; +} + +} // namespace input_method +} // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/mock_input_method_delegate.h b/chrome/browser/chromeos/input_method/mock_input_method_delegate.h new file mode 100644 index 0000000..be03d41 --- /dev/null +++ b/chrome/browser/chromeos/input_method/mock_input_method_delegate.h @@ -0,0 +1,68 @@ +// Copyright (c) 2012 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_INPUT_METHOD_MOCK_INPUT_METHOD_DELEGATE_H_ +#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_MOCK_INPUT_METHOD_DELEGATE_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chrome/browser/chromeos/input_method/input_method_delegate.h" + +namespace chromeos { +namespace input_method { + +class MockInputMethodDelegate : public InputMethodDelegate { + public: + MockInputMethodDelegate(); + virtual ~MockInputMethodDelegate(); + + // InputMethodDelegate implementation: + virtual void SetSystemInputMethod( + const std::string& input_method) OVERRIDE; + virtual void SetUserInputMethod(const std::string& input_method) OVERRIDE; + virtual std::string GetHardwareKeyboardLayout() const OVERRIDE; + virtual std::string GetActiveLocale() const OVERRIDE; + + int update_system_input_method_count() const { + return update_system_input_method_count_; + } + + int update_user_input_method_count() const { + return update_user_input_method_count_; + } + + void set_hardware_keyboard_layout(const std::string& value) { + hardware_keyboard_layout_ = value; + } + + void set_active_locale(const std::string& value) { + active_locale_ = value; + } + + const std::string& system_input_method() const { + return system_input_method_; + } + + const std::string& user_input_method() const { + return user_input_method_; + } + + private: + std::string hardware_keyboard_layout_; + std::string active_locale_; + std::string system_input_method_; + std::string user_input_method_; + + int update_system_input_method_count_; + int update_user_input_method_count_; + + DISALLOW_COPY_AND_ASSIGN(MockInputMethodDelegate); +}; + +} // namespace input_method +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_MOCK_INPUT_METHOD_DELEGATE_H_ diff --git a/chrome/browser/chromeos/input_method/mock_input_method_manager.cc b/chrome/browser/chromeos/input_method/mock_input_method_manager.cc index d7bdc87..7a1facd 100644 --- a/chrome/browser/chromeos/input_method/mock_input_method_manager.cc +++ b/chrome/browser/chromeos/input_method/mock_input_method_manager.cc @@ -12,7 +12,7 @@ MockInputMethodManager::MockInputMethodManager() remove_observer_count_(0), set_state_count_(0), last_state_(STATE_TERMINATING), - util_(whitelist_.GetSupportedInputMethods()) { + util_(&delegate_, whitelist_.GetSupportedInputMethods()) { } MockInputMethodManager::~MockInputMethodManager() { @@ -143,5 +143,14 @@ InputMethodUtil* MockInputMethodManager::GetInputMethodUtil() { return &util_; } +void MockInputMethodManager::set_application_locale(const std::string& value) { + delegate_.set_active_locale(value); +} + +void MockInputMethodManager::set_hardware_keyboard_layout( + const std::string& value) { + delegate_.set_hardware_keyboard_layout(value); +} + } // namespace input_method } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/mock_input_method_manager.h b/chrome/browser/chromeos/input_method/mock_input_method_manager.h index d5f0cc8..31425a8 100644 --- a/chrome/browser/chromeos/input_method/mock_input_method_manager.h +++ b/chrome/browser/chromeos/input_method/mock_input_method_manager.h @@ -8,6 +8,7 @@ #include "chrome/browser/chromeos/input_method/input_method_manager.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/input_method_whitelist.h" +#include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" #include "chrome/browser/chromeos/input_method/mock_xkeyboard.h" namespace chromeos { @@ -66,6 +67,10 @@ class MockInputMethodManager : public InputMethodManager { current_input_method_id_ = input_method_id; } + // Set values that will be provided to the InputMethodUtil. + void set_application_locale(const std::string& value); + void set_hardware_keyboard_layout(const std::string& value); + // TODO(yusukes): Add more variables for counting the numbers of the API calls int add_observer_count_; int remove_observer_count_; @@ -77,6 +82,7 @@ class MockInputMethodManager : public InputMethodManager { std::string current_input_method_id_; InputMethodWhitelist whitelist_; + MockInputMethodDelegate delegate_; // used by util_ InputMethodUtil util_; MockXKeyboard xkeyboard_; diff --git a/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc b/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc index 24b3a46..ab3cc3a 100644 --- a/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc +++ b/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc @@ -13,6 +13,7 @@ #include "base/message_loop.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/input_method_whitelist.h" +#include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" #include "content/public/test/test_browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/x/x11_util.h" @@ -29,7 +30,7 @@ namespace { class XKeyboardTest : public testing::Test { public: XKeyboardTest() - : util_(whitelist_.GetSupportedInputMethods()), + : util_(&delegate_, whitelist_.GetSupportedInputMethods()), ui_thread_(BrowserThread::UI, &message_loop_) { } @@ -41,6 +42,7 @@ class XKeyboardTest : public testing::Test { xkey_.reset(); } + MockInputMethodDelegate delegate_; InputMethodWhitelist whitelist_; InputMethodUtil util_; scoped_ptr<XKeyboard> xkey_; |