diff options
author | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-17 10:56:17 +0000 |
---|---|---|
committer | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-17 10:56:17 +0000 |
commit | 39699140299fd70d13c53a446976318f683f57b3 (patch) | |
tree | 34c99dfe4364dde521ab12cfe8d0886bcf576f72 /chrome/browser/chromeos/input_method | |
parent | d741fa57ad0a097b74204c88b6beb70803b6353e (diff) | |
download | chromium_src-39699140299fd70d13c53a446976318f683f57b3.zip chromium_src-39699140299fd70d13c53a446976318f683f57b3.tar.gz chromium_src-39699140299fd70d13c53a446976318f683f57b3.tar.bz2 |
Support comma separated hardware keyboard layout value.
To be able to use comma-separated keyboard_layout, extends
GetHardwareKeyboardLayout and EnableLoginLayouts.
This change does not break backward compatibility.
BUG=334576
TEST=manually done.
Review URL: https://codereview.chromium.org/139803010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251653 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/input_method')
10 files changed, 246 insertions, 121 deletions
diff --git a/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc b/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc index ddfbe69..aee6783 100644 --- a/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/prefs/pref_service.h" +#include "base/strings/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" #include "ui/base/l10n/l10n_util.h" @@ -13,17 +14,21 @@ namespace chromeos { namespace input_method { -InputMethodDelegateImpl::InputMethodDelegateImpl() {} - -std::string InputMethodDelegateImpl::GetHardwareKeyboardLayout() const { - if (g_browser_process) { - PrefService* 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(); +InputMethodDelegateImpl::InputMethodDelegateImpl() { +} + +InputMethodDelegateImpl::~InputMethodDelegateImpl() { +} + +std::string InputMethodDelegateImpl::GetHardwareKeyboardLayouts() const { + if (!g_browser_process) + return ""; + + PrefService* local_state = g_browser_process->local_state(); + if (!local_state) + return ""; + + return local_state->GetString(prefs::kHardwareKeyboardLayout); } base::string16 InputMethodDelegateImpl::GetLocalizedString( @@ -40,5 +45,11 @@ base::string16 InputMethodDelegateImpl::GetDisplayLanguageName( true); } +void InputMethodDelegateImpl::SetHardwareKeyboardLayoutForTesting( + const std::string& layout) { + NOTREACHED() << "Use FakeInputMethodDelegate for hardware keyboard layout " + << "testing purpose."; +} + } // 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 index 4d1920a..556aad2 100644 --- a/chrome/browser/chromeos/input_method/input_method_delegate_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_delegate_impl.h @@ -19,12 +19,15 @@ namespace input_method { class InputMethodDelegateImpl : public InputMethodDelegate { public: InputMethodDelegateImpl(); + virtual ~InputMethodDelegateImpl(); // InputMethodDelegate implementation. - virtual std::string GetHardwareKeyboardLayout() const OVERRIDE; + virtual std::string GetHardwareKeyboardLayouts() const OVERRIDE; virtual base::string16 GetLocalizedString(int resource_id) const OVERRIDE; virtual base::string16 GetDisplayLanguageName( const std::string& language_code) const OVERRIDE; + virtual void SetHardwareKeyboardLayoutForTesting( + const std::string& layout) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(InputMethodDelegateImpl); 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 719aecc..3432e7b 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc @@ -161,34 +161,40 @@ const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId( void InputMethodManagerImpl::EnableLoginLayouts( const std::string& language_code, - const std::string& initial_layout) { + const std::vector<std::string>& initial_layouts) { if (state_ == STATE_TERMINATING) return; - std::vector<std::string> candidates; + // First, hardware keyboard layout should be shown. + std::vector<std::string> candidates = + util_.GetHardwareLoginInputMethodIds(); + + // Seocnd, locale based input method should be shown. // Add input methods associated with the language. + std::vector<std::string> layouts_from_locale; util_.GetInputMethodIdsFromLanguageCode(language_code, kKeyboardLayoutsOnly, - &candidates); - // Add the hardware keyboard as well. We should always add this so users - // can use the hardware keyboard on the login screen and the screen locker. - candidates.push_back(util_.GetHardwareLoginInputMethodId()); + &layouts_from_locale); + candidates.insert(candidates.end(), layouts_from_locale.begin(), + layouts_from_locale.end()); std::vector<std::string> layouts; // First, add the initial input method ID, if it's requested, to // layouts, so it appears first on the list of active input // methods at the input language status menu. - if (util_.IsValidInputMethodId(initial_layout)) { - if (!IsLoginKeyboard(initial_layout)) { - DVLOG(1) - << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" - << initial_layout; - } else { - layouts.push_back(initial_layout); + for (size_t i = 0; i < initial_layouts.size(); ++i) { + if (util_.IsValidInputMethodId(initial_layouts[i])) { + if (IsLoginKeyboard(initial_layouts[i])) { + layouts.push_back(initial_layouts[i]); + } else { + DVLOG(1) + << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" + << initial_layouts[i]; + } + } else if (!initial_layouts[i].empty()) { + DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " + << initial_layouts[i]; } - } else if (!initial_layout.empty()) { - DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " - << initial_layout; } // Add candidates to layouts, while skipping duplicates. @@ -208,7 +214,8 @@ void InputMethodManagerImpl::EnableLoginLayouts( if (active_input_method_ids_.size() > 1) MaybeInitializeCandidateWindowController(); - ChangeInputMethod(initial_layout); // you can pass empty |initial_layout|. + // you can pass empty |initial_layout|. + ChangeInputMethod(initial_layouts.empty() ? "" : initial_layouts[0]); } // Adds new input method to given list. @@ -251,7 +258,7 @@ bool InputMethodManagerImpl::EnableInputMethod( return true; } -bool InputMethodManagerImpl::EnableInputMethods( +bool InputMethodManagerImpl::ReplaceEnabledInputMethods( const std::vector<std::string>& new_active_input_method_ids) { if (state_ == STATE_TERMINATING) return false; @@ -264,7 +271,7 @@ bool InputMethodManagerImpl::EnableInputMethods( &new_active_input_method_ids_filtered); if (new_active_input_method_ids_filtered.empty()) { - DVLOG(1) << "EnableInputMethods: No valid input method ID"; + DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID"; return false; } @@ -541,7 +548,7 @@ void InputMethodManagerImpl::SetEnabledExtensionImes( } } -void InputMethodManagerImpl::SetInputMethodDefault() { +void InputMethodManagerImpl::SetInputMethodLoginDefault() { // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty // and US dvorak keyboard layouts. if (g_browser_process && g_browser_process->local_state()) { @@ -550,12 +557,14 @@ void InputMethodManagerImpl::SetInputMethodDefault() { PrefService* prefs = g_browser_process->local_state(); std::string initial_input_method_id = prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); + std::vector<std::string> input_methods_to_be_enabled; if (initial_input_method_id.empty()) { // If kPreferredKeyboardLayout is not specified, use the hardware layout. - initial_input_method_id = - GetInputMethodUtil()->GetHardwareInputMethodId(); + input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); + } else { + input_methods_to_be_enabled.push_back(initial_input_method_id); } - EnableLoginLayouts(locale, initial_input_method_id); + EnableLoginLayouts(locale, input_methods_to_be_enabled); } } @@ -787,25 +796,32 @@ void InputMethodManagerImpl::OnScreenLocked() { saved_current_input_method_ = current_input_method_; saved_active_input_method_ids_ = active_input_method_ids_; - const std::string hardware_keyboard_id = util_.GetHardwareInputMethodId(); - // We'll add the hardware keyboard if it's not included in - // |active_input_method_list| so that the user can always use the hardware - // keyboard on the screen locker. - bool should_add_hardware_keyboard = true; + std::set<std::string> added_ids_; + + const std::vector<std::string>& hardware_keyboard_ids = + util_.GetHardwareLoginInputMethodIds(); active_input_method_ids_.clear(); for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { const std::string& input_method_id = saved_active_input_method_ids_[i]; // Skip if it's not a keyboard layout. Drop input methods including // extension ones. - if (!IsLoginKeyboard(input_method_id)) + if (!IsLoginKeyboard(input_method_id) || + added_ids_.find(input_method_id) != added_ids_.end()) continue; active_input_method_ids_.push_back(input_method_id); - if (input_method_id == hardware_keyboard_id) - should_add_hardware_keyboard = false; + added_ids_.insert(input_method_id); + } + + // We'll add the hardware keyboard if it's not included in + // |active_input_method_ids_| so that the user can always use the hardware + // keyboard on the screen locker. + for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) { + if (added_ids_.find(hardware_keyboard_ids[i]) == added_ids_.end()) { + active_input_method_ids_.push_back(hardware_keyboard_ids[i]); + added_ids_.insert(hardware_keyboard_ids[i]); + } } - if (should_add_hardware_keyboard) - active_input_method_ids_.push_back(hardware_keyboard_id); ChangeInputMethod(current_input_method_.id()); } 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 f24152e..889a3f2 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h @@ -59,9 +59,10 @@ class InputMethodManagerImpl : public InputMethodManager, virtual size_t GetNumActiveInputMethods() const OVERRIDE; virtual const InputMethodDescriptor* GetInputMethodFromId( const std::string& input_method_id) const OVERRIDE; - virtual void EnableLoginLayouts(const std::string& language_code, - const std::string& initial_layout) OVERRIDE; - virtual bool EnableInputMethods( + virtual void EnableLoginLayouts( + const std::string& language_code, + const std::vector<std::string>& initial_layouts) OVERRIDE; + virtual bool ReplaceEnabledInputMethods( const std::vector<std::string>& new_active_input_method_ids) OVERRIDE; virtual bool EnableInputMethod(const std::string& new_active_input_method_id) OVERRIDE; @@ -74,7 +75,7 @@ class InputMethodManagerImpl : public InputMethodManager, virtual void GetInputMethodExtensions( InputMethodDescriptors* result) OVERRIDE; virtual void SetEnabledExtensionImes(std::vector<std::string>* ids) OVERRIDE; - virtual void SetInputMethodDefault() OVERRIDE; + virtual void SetInputMethodLoginDefault() OVERRIDE; virtual bool SwitchToNextInputMethod() OVERRIDE; virtual bool SwitchToPreviousInputMethod( const ui::Accelerator& accelerator) OVERRIDE; 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 18428df..cc22f78 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 @@ -62,6 +62,7 @@ class InputMethodManagerImplTest : public testing::Test { delegate_ = new FakeInputMethodDelegate(); manager_.reset(new InputMethodManagerImpl( scoped_ptr<InputMethodDelegate>(delegate_))); + manager_->GetInputMethodUtil()->UpdateHardwareLayoutCache(); candidate_window_controller_ = new MockCandidateWindowController; manager_->SetCandidateWindowControllerForTesting( candidate_window_controller_); @@ -233,11 +234,14 @@ TEST_F(InputMethodManagerImplTest, TestCandidateWindowObserver) { TEST_F(InputMethodManagerImplTest, TestObserver) { // For http://crbug.com/19655#c11 - (3). browser_state_monitor_unittest.cc is // also for the scenario. + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:us::eng"); + TestObserver observer; InitComponentExtension(); manager_->AddObserver(&observer); EXPECT_EQ(0, observer.input_method_changed_count_); - manager_->EnableLoginLayouts("en-US", "xkb:us::eng"); + manager_->EnableLoginLayouts("en-US", keyboard_layouts); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(1, observer.input_method_property_changed_count_); manager_->ChangeInputMethod("xkb:us:dvorak:eng"); @@ -283,46 +287,84 @@ TEST_F(InputMethodManagerImplTest, TestGetSupportedInputMethods) { TEST_F(InputMethodManagerImplTest, TestEnableLayouts) { // Currently 5 keyboard layouts are supported for en-US, and 1 for ja. See // ibus_input_method.txt. + std::vector<std::string> keyboard_layouts; + InitComponentExtension(); - manager_->EnableLoginLayouts("en-US", ""); + manager_->EnableLoginLayouts("en-US", keyboard_layouts); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); for (size_t i = 0; i < manager_->GetActiveInputMethodIds().size(); ++i) LOG(ERROR) << manager_->GetActiveInputMethodIds().at(i); // For http://crbug.com/19655#c11 - (5) // The hardware keyboard layout "xkb:us::eng" is always active, hence 2U. - manager_->EnableLoginLayouts("ja", ""); // Japanese + manager_->EnableLoginLayouts("ja", keyboard_layouts); // Japanese EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); } TEST_F(InputMethodManagerImplTest, TestEnableLayoutsAndCurrentInputMethod) { // For http://crbug.com/329061 - manager_->EnableLoginLayouts("en-US", "xkb:se::swe"); + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:se::swe"); + + manager_->EnableLoginLayouts("en-US", keyboard_layouts); const std::string im_id = manager_->GetCurrentInputMethod().id(); EXPECT_EQ("xkb:se::swe", im_id); } TEST_F(InputMethodManagerImplTest, TestEnableLayoutsNonUsHardwareKeyboard) { // The physical layout is French. - delegate_->set_hardware_keyboard_layout("xkb:fr::fra"); - manager_->EnableLoginLayouts("en-US", ""); + manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( + "xkb:fr::fra"); + manager_->EnableLoginLayouts( + "en-US", + manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); EXPECT_EQ(6U, manager_->GetNumActiveInputMethods()); // 5 + French // The physical layout is Japanese. - delegate_->set_hardware_keyboard_layout("xkb:jp::jpn"); - manager_->EnableLoginLayouts("ja", ""); + manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( + "xkb:jp::jpn"); + manager_->EnableLoginLayouts( + "ja", + manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); // "xkb:us::eng" is not needed, hence 1. EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); // The physical layout is Russian. - delegate_->set_hardware_keyboard_layout("xkb:ru::rus"); - manager_->EnableLoginLayouts("ru", ""); + manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( + "xkb:ru::rus"); + manager_->EnableLoginLayouts( + "ru", + manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); // "xkb:us::eng" only. EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ("xkb:us::eng", manager_->GetActiveInputMethodIds().front()); } +TEST_F(InputMethodManagerImplTest, TestEnableMultipleHardwareKeyboardLayout) { + // The physical layouts are French and Hungarian. + manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( + "xkb:fr::fra,xkb:hu::hun"); + manager_->EnableLoginLayouts( + "en-US", + manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); + // 5 + French + Hungarian + EXPECT_EQ(7U, manager_->GetNumActiveInputMethods()); +} + +TEST_F(InputMethodManagerImplTest, + TestEnableMultipleHardwareKeyboardLayout_NoLoginKeyboard) { + // The physical layouts are English (US) and Russian. + manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( + "xkb:us::eng,xkb:ru::rus"); + manager_->EnableLoginLayouts( + "ru", + manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); + // xkb:us:eng + EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); +} + TEST_F(InputMethodManagerImplTest, TestActiveInputMethods) { - manager_->EnableLoginLayouts("ja", ""); // Japanese + std::vector<std::string> keyboard_layouts; + manager_->EnableLoginLayouts("ja", keyboard_layouts); // Japanese EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); scoped_ptr<InputMethodDescriptors> methods( manager_->GetActiveInputMethods()); @@ -346,7 +388,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableTwoLayouts) { std::vector<std::string> ids; ids.push_back("xkb:us:dvorak:eng"); ids.push_back("xkb:us:colemak:eng"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); // Since all the IDs added avobe are keyboard layouts, Start() should not be // called. @@ -355,7 +397,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableTwoLayouts) { EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); // Disable Dvorak. ids.erase(ids.begin()); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(2, observer.input_method_changed_count_); EXPECT_EQ(ids[0], // colemak @@ -374,7 +416,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableThreeLayouts) { ids.push_back("xkb:us::eng"); ids.push_back("xkb:us:dvorak:eng"); ids.push_back("xkb:us:colemak:eng"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); @@ -386,7 +428,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableThreeLayouts) { EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); // Disable Dvorak. ids.erase(ids.begin() + 1); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(3, observer.input_method_changed_count_); EXPECT_EQ(ids[0], // US Qwerty @@ -404,7 +446,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme) { std::vector<std::string> ids; ids.push_back("xkb:us:dvorak:eng"); ids.push_back(kNaclMozcUsId); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); @@ -415,7 +457,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme) { EXPECT_EQ("us", xkeyboard_->last_layout_); // Disable Mozc. ids.erase(ids.begin() + 1); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); @@ -430,14 +472,14 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme2) { std::vector<std::string> ids; ids.push_back("xkb:us:dvorak:eng"); ids.push_back(kNaclMozcUsId); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); // Disable Dvorak. ids.erase(ids.begin()); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(ids[0], // Mozc manager_->GetCurrentInputMethod().id()); @@ -453,7 +495,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableImes) { std::vector<std::string> ids; ids.push_back(kExt2Engine1Id); ids.push_back("mozc-dv"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us", xkeyboard_->last_layout_); @@ -467,7 +509,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableUnknownIds) { std::vector<std::string> ids; ids.push_back("xkb:tl::tlh"); // Klingon, which is not supported. ids.push_back("unknown-super-cool-ime"); - EXPECT_FALSE(manager_->EnableInputMethods(ids)); + EXPECT_FALSE(manager_->ReplaceEnabledInputMethods(ids)); // TODO(yusukes): Should we fall back to the hardware keyboard layout in this // case? @@ -485,7 +527,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutsThenLock) { std::vector<std::string> ids; ids.push_back("xkb:us::eng"); ids.push_back("xkb:us:dvorak:eng"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); @@ -527,7 +569,7 @@ TEST_F(InputMethodManagerImplTest, SwitchInputMethodTest) { ids.push_back("xkb:us:dvorak:eng"); ids.push_back(kExt2Engine2Id); ids.push_back(kExt2Engine1Id); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); @@ -568,7 +610,7 @@ TEST_F(InputMethodManagerImplTest, TestXkbSetting) { ids.push_back("xkb:us:colemak:eng"); ids.push_back(kNaclMozcJpId); ids.push_back(kNaclMozcUsId); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(4U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(1, xkeyboard_->set_current_keyboard_layout_by_name_count_); // See input_methods.txt for an expected XKB layout name. @@ -587,7 +629,7 @@ TEST_F(InputMethodManagerImplTest, TestXkbSetting) { EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); // Disable Dvorak. ids.erase(ids.begin()); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(6, xkeyboard_->set_current_keyboard_layout_by_name_count_); EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_); @@ -615,7 +657,7 @@ TEST_F(InputMethodManagerImplTest, TestGetCurrentInputMethodProperties) { std::vector<std::string> ids; ids.push_back("xkb:us::eng"); ids.push_back(kNaclMozcUsId); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty()); manager_->ChangeInputMethod(kNaclMozcUsId); @@ -642,7 +684,7 @@ TEST_F(InputMethodManagerImplTest, TestGetCurrentInputMethodPropertiesTwoImes) { std::vector<std::string> ids; ids.push_back(kNaclMozcUsId); // Japanese ids.push_back(kExt2Engine1Id); // T-Chinese - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty()); @@ -676,8 +718,10 @@ TEST_F(InputMethodManagerImplTest, TestNextInputMethod) { TestObserver observer; manager_->AddObserver(&observer); InitComponentExtension(); + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:us::eng"); // For http://crbug.com/19655#c11 - (1) - manager_->EnableLoginLayouts("en-US", "xkb:us::eng"); + manager_->EnableLoginLayouts("en-US", keyboard_layouts); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us", xkeyboard_->last_layout_); @@ -715,7 +759,9 @@ TEST_F(InputMethodManagerImplTest, TestPreviousInputMethod) { ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); keyup_accelerator.set_type(ui::ET_KEY_RELEASED); - manager_->EnableLoginLayouts("en-US", "xkb:us::eng"); + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:us::eng"); + manager_->EnableLoginLayouts("en-US", keyboard_layouts); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us", xkeyboard_->last_layout_); @@ -773,7 +819,7 @@ TEST_F(InputMethodManagerImplTest, std::vector<std::string> ids; ids.push_back("xkb:us:dvorak:eng"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); // Ctrl+Space accelerator should not be consumed if there is only one active @@ -788,7 +834,9 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithUsLayouts) { TestObserver observer; manager_->AddObserver(&observer); InitComponentExtension(); - manager_->EnableLoginLayouts("en-US", "xkb:us::eng"); + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:us::eng"); + manager_->EnableLoginLayouts("en-US", keyboard_layouts); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us", xkeyboard_->last_layout_); @@ -825,7 +873,9 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpLayout) { ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); keyup_accelerator.set_type(ui::ET_KEY_RELEASED); - manager_->EnableLoginLayouts("ja", "xkb:us::eng"); + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:us::eng"); + manager_->EnableLoginLayouts("ja", keyboard_layouts); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us", xkeyboard_->last_layout_); @@ -857,7 +907,7 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpIme) { std::vector<std::string> ids; ids.push_back("xkb:jp::jpn"); ids.push_back(kNaclMozcJpId); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("jp", xkeyboard_->last_layout_); EXPECT_TRUE(manager_->SwitchInputMethod( @@ -887,7 +937,7 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpIme) { // Add Dvorak. ids.push_back("xkb:us:dvorak:eng"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("jp", xkeyboard_->last_layout_); EXPECT_TRUE(manager_->SwitchInputMethod( @@ -907,7 +957,7 @@ TEST_F(InputMethodManagerImplTest, TestAddRemoveExtensionInputMethods) { manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); std::vector<std::string> ids; ids.push_back("xkb:us:dvorak:eng"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], @@ -989,7 +1039,7 @@ TEST_F(InputMethodManagerImplTest, TestAddExtensionInputThenLockScreen) { manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); std::vector<std::string> ids; ids.push_back("xkb:us::eng"); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); @@ -1057,7 +1107,7 @@ TEST_F(InputMethodManagerImplTest, manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); std::vector<std::string> ids; ids.push_back(kNaclMozcUsId); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); manager_->ChangeInputMethod(kNaclMozcUsId); @@ -1071,7 +1121,7 @@ TEST_F(InputMethodManagerImplTest, std::vector<std::string> ids; ids.push_back(kNaclMozcUsId); ids.push_back(kNaclMozcJpId); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); manager_->ChangeInputMethod(kNaclMozcUsId); manager_->ChangeInputMethod(kNaclMozcJpId); @@ -1088,7 +1138,7 @@ TEST_F(InputMethodManagerImplTest, ime_list_[0].engines[0].engine_id); std::vector<std::string> ids; ids.push_back(ext_id); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); manager_->ChangeInputMethod(ext_id); @@ -1108,7 +1158,7 @@ TEST_F(InputMethodManagerImplTest, std::vector<std::string> ids; ids.push_back(ext_id1); ids.push_back(ext_id2); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); manager_->ChangeInputMethod(ext_id1); manager_->ChangeInputMethod(ext_id2); @@ -1126,7 +1176,7 @@ TEST_F(InputMethodManagerImplTest, ime_list_[0].engines[0].engine_id); std::vector<std::string> ids; ids.push_back(ext_id); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(ext_id, manager_->GetCurrentInputMethod().id()); } @@ -1144,7 +1194,7 @@ TEST_F(InputMethodManagerImplTest, std::vector<std::string> ids; ids.push_back(ext_id1); ids.push_back(ext_id2); - EXPECT_TRUE(manager_->EnableInputMethods(ids)); + EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(ext_id1, manager_->GetCurrentInputMethod().id()); manager_->ChangeInputMethod(ext_id2); diff --git a/chrome/browser/chromeos/input_method/input_method_util.cc b/chrome/browser/chromeos/input_method/input_method_util.cc index 956ce40..2c0f751 100644 --- a/chrome/browser/chromeos/input_method/input_method_util.cc +++ b/chrome/browser/chromeos/input_method/input_method_util.cc @@ -17,6 +17,8 @@ #include "base/strings/utf_string_conversions.h" #include "chromeos/ime/component_extension_ime_manager.h" #include "chromeos/ime/extension_ime_util.h" +// For SetHardwareKeyboardLayoutForTesting. +#include "chromeos/ime/fake_input_method_delegate.h" #include "chromeos/ime/input_method_delegate.h" // TODO(nona): move this header from this file. #include "grit/generated_resources.h" @@ -609,25 +611,49 @@ std::string InputMethodUtil::GetLanguageDefaultInputMethodId( return std::string(); } -std::string InputMethodUtil::GetHardwareInputMethodId() const { - const std::string input_method_id = delegate_->GetHardwareKeyboardLayout(); +void InputMethodUtil::UpdateHardwareLayoutCache() { + DCHECK(thread_checker_.CalledOnValidThread()); + hardware_layouts_.clear(); + hardware_login_layouts_.clear(); + Tokenize(delegate_->GetHardwareKeyboardLayouts(), ",", &hardware_layouts_); - if (input_method_id.empty()) { + for (size_t i = 0; i < hardware_layouts_.size(); ++i) { + if (IsLoginKeyboard(hardware_layouts_[i])) + hardware_login_layouts_.push_back(hardware_layouts_[i]); + } + if (hardware_layouts_.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 // present (ex. Cr48 doen't have that file). - return GetFallbackInputMethodDescriptor().id(); + hardware_layouts_.push_back(GetFallbackInputMethodDescriptor().id()); } - return input_method_id; + + if (hardware_login_layouts_.empty()) + hardware_login_layouts_.push_back(GetFallbackInputMethodDescriptor().id()); } -std::string InputMethodUtil::GetHardwareLoginInputMethodId() const { - const std::string input_method_id = GetHardwareInputMethodId(); +void InputMethodUtil::SetHardwareKeyboardLayoutForTesting( + const std::string& layout) { + delegate_->SetHardwareKeyboardLayoutForTesting(layout); + UpdateHardwareLayoutCache(); +} - if (!IsLoginKeyboard(input_method_id)) - return GetFallbackInputMethodDescriptor().id(); +const std::vector<std::string>& + InputMethodUtil::GetHardwareInputMethodIds() { + DCHECK(thread_checker_.CalledOnValidThread()); + // Once the initialization is done, at least one input method should be set. + if (hardware_layouts_.empty()) + UpdateHardwareLayoutCache(); + return hardware_layouts_; +} - return input_method_id; +const std::vector<std::string>& + InputMethodUtil::GetHardwareLoginInputMethodIds() { + DCHECK(thread_checker_.CalledOnValidThread()); + // Once the initialization is done, at least one input method should be set. + if (hardware_login_layouts_.empty()) + UpdateHardwareLayoutCache(); + return hardware_login_layouts_; } bool InputMethodUtil::IsLoginKeyboard(const std::string& input_method_id) diff --git a/chrome/browser/chromeos/input_method/input_method_util.h b/chrome/browser/chromeos/input_method/input_method_util.h index 50092b4..a89ebd7 100644 --- a/chrome/browser/chromeos/input_method/input_method_util.h +++ b/chrome/browser/chromeos/input_method/input_method_util.h @@ -13,6 +13,7 @@ #include "base/containers/hash_tables.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" +#include "base/threading/thread_checker.h" #include "chromeos/ime/input_method_descriptor.h" namespace chromeos { @@ -97,12 +98,24 @@ class InputMethodUtil { // Returns empty string on error. std::string GetLanguageDefaultInputMethodId(const std::string& language_code); - // Returns the input method ID of the hardware keyboard. e.g. "xkb:us::eng" - // for the US Qwerty keyboard. - std::string GetHardwareInputMethodId() const; + // Updates the internal cache of hardware layouts. + void UpdateHardwareLayoutCache(); - // Returns the login-allowed input method ID of the hardware keyboard. - std::string GetHardwareLoginInputMethodId() const; + // Set hardware keyboard layout for testing purpose. This is for simulating + // "keyboard_layout" entry in VPD values. + void SetHardwareKeyboardLayoutForTesting(const std::string& layout); + + // Fills the input method IDs of the hardware keyboard. e.g. "xkb:us::eng" + // for US Qwerty keyboard or "xkb:ru::rus" for Russian keyboard. + const std::vector<std::string>& GetHardwareInputMethodIds(); + + // Returns the login-allowed input method ID of the hardware keyboard, e.g. + // "xkb:us::eng" but not include non-login keyboard like "xkb:ru::rus". Please + // note that this is not a subset of returned value of + // GetHardwareInputMethodIds. If GetHardwareInputMethodIds returns only + // non-login keyboard, this function will returns "xkb:us::eng" as the + // fallback keyboard. + const std::vector<std::string>& GetHardwareLoginInputMethodIds(); // Returns true if given input method can be used to input login data. bool IsLoginKeyboard(const std::string& input_method_id) const; @@ -173,6 +186,10 @@ class InputMethodUtil { InputMethodDelegate* delegate_; + base::ThreadChecker thread_checker_; + std::vector<std::string> hardware_layouts_; + std::vector<std::string> hardware_login_layouts_; + DISALLOW_COPY_AND_ASSIGN(InputMethodUtil); }; 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 8c0594f..a4533a2 100644 --- a/chrome/browser/chromeos/input_method/mock_input_method_manager.cc +++ b/chrome/browser/chromeos/input_method/mock_input_method_manager.cc @@ -74,10 +74,10 @@ const InputMethodDescriptor* MockInputMethodManager::GetInputMethodFromId( void MockInputMethodManager::EnableLoginLayouts( const std::string& language_code, - const std::string& initial_layout) { + const std::vector<std::string>& initial_layout) { } -bool MockInputMethodManager::EnableInputMethods( +bool MockInputMethodManager::ReplaceEnabledInputMethods( const std::vector<std::string>& new_active_input_method_ids) { return true; } @@ -111,7 +111,7 @@ void MockInputMethodManager::SetEnabledExtensionImes( std::vector<std::string>* ids) { } -void MockInputMethodManager::SetInputMethodDefault() { +void MockInputMethodManager::SetInputMethodLoginDefault() { } bool MockInputMethodManager::SwitchToNextInputMethod() { @@ -170,11 +170,6 @@ 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); -} - bool MockInputMethodManager::IsLoginKeyboard( const std::string& layout) const { return true; 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 ef8001f..794db45 100644 --- a/chrome/browser/chromeos/input_method/mock_input_method_manager.h +++ b/chrome/browser/chromeos/input_method/mock_input_method_manager.h @@ -36,9 +36,10 @@ class MockInputMethodManager : public InputMethodManager { virtual size_t GetNumActiveInputMethods() const OVERRIDE; virtual const InputMethodDescriptor* GetInputMethodFromId( const std::string& input_method_id) const OVERRIDE; - virtual void EnableLoginLayouts(const std::string& language_code, - const std::string& initial_layout) OVERRIDE; - virtual bool EnableInputMethods( + virtual void EnableLoginLayouts( + const std::string& language_code, + const std::vector<std::string>& initial_layout) OVERRIDE; + virtual bool ReplaceEnabledInputMethods( const std::vector<std::string>& new_active_input_method_ids) OVERRIDE; virtual bool EnableInputMethod( const std::string& new_active_input_method_id) OVERRIDE; @@ -51,7 +52,7 @@ class MockInputMethodManager : public InputMethodManager { virtual void GetInputMethodExtensions( InputMethodDescriptors* result) OVERRIDE; virtual void SetEnabledExtensionImes(std::vector<std::string>* ids) OVERRIDE; - virtual void SetInputMethodDefault() OVERRIDE; + virtual void SetInputMethodLoginDefault() OVERRIDE; virtual bool SwitchToNextInputMethod() OVERRIDE; virtual bool SwitchToPreviousInputMethod( const ui::Accelerator& accelerator) OVERRIDE; @@ -74,7 +75,6 @@ class MockInputMethodManager : public InputMethodManager { // 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_; diff --git a/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc b/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc index b21a5bf..7ec8b6f 100644 --- a/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc +++ b/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc @@ -125,8 +125,11 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, Bounds) { InputMethodManager* imm = InputMethodManager::Get(); ASSERT_TRUE(imm); + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:fr::fra"); + // Add keyboard layouts to enable the mode indicator. - imm->EnableLoginLayouts("fr", "xkb:fr::fra"); + imm->EnableLoginLayouts("fr", keyboard_layouts); ASSERT_LT(1UL, imm->GetNumActiveInputMethods()); chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window = @@ -189,8 +192,11 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, NumOfWidgets) { InputMethodManager* imm = InputMethodManager::Get(); ASSERT_TRUE(imm); + std::vector<std::string> keyboard_layouts; + keyboard_layouts.push_back("xkb:fr::fra"); + // Add keyboard layouts to enable the mode indicator. - imm->EnableLoginLayouts("fr", "xkb:fr::fra"); + imm->EnableLoginLayouts("fr", keyboard_layouts); ASSERT_LT(1UL, imm->GetNumActiveInputMethods()); chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window = |