summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-17 10:56:17 +0000
committernona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-17 10:56:17 +0000
commit39699140299fd70d13c53a446976318f683f57b3 (patch)
tree34c99dfe4364dde521ab12cfe8d0886bcf576f72
parentd741fa57ad0a097b74204c88b6beb70803b6353e (diff)
downloadchromium_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
-rw-r--r--chrome/browser/chromeos/base/locale_util.cc2
-rw-r--r--chrome/browser/chromeos/chrome_browser_main_chromeos.cc15
-rw-r--r--chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc6
-rw-r--r--chrome/browser/chromeos/input_method/input_method_delegate_impl.cc33
-rw-r--r--chrome/browser/chromeos/input_method/input_method_delegate_impl.h5
-rw-r--r--chrome/browser/chromeos/input_method/input_method_manager_impl.cc82
-rw-r--r--chrome/browser/chromeos/input_method/input_method_manager_impl.h9
-rw-r--r--chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc134
-rw-r--r--chrome/browser/chromeos/input_method/input_method_util.cc46
-rw-r--r--chrome/browser/chromeos/input_method/input_method_util.h27
-rw-r--r--chrome/browser/chromeos/input_method/mock_input_method_manager.cc11
-rw-r--r--chrome/browser/chromeos/input_method/mock_input_method_manager.h10
-rw-r--r--chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc10
-rw-r--r--chrome/browser/chromeos/login/login_display_host_impl.cc25
-rw-r--r--chrome/browser/chromeos/preferences.cc15
-rw-r--r--chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc2
-rw-r--r--chromeos/ime/fake_input_method_delegate.cc7
-rw-r--r--chromeos/ime/fake_input_method_delegate.h6
-rw-r--r--chromeos/ime/input_method_delegate.h9
-rw-r--r--chromeos/ime/input_method_manager.h15
20 files changed, 314 insertions, 155 deletions
diff --git a/chrome/browser/chromeos/base/locale_util.cc b/chrome/browser/chromeos/base/locale_util.cc
index 176a105..cfbb1b0 100644
--- a/chrome/browser/chromeos/base/locale_util.cc
+++ b/chrome/browser/chromeos/base/locale_util.cc
@@ -65,7 +65,7 @@ void FinishSwitchLanguage(scoped_ptr<SwitchLanguageData> data) {
input_method::InputMethodManager::Get();
manager->EnableLoginLayouts(
data->locale,
- manager->GetInputMethodUtil()->GetHardwareLoginInputMethodId());
+ manager->GetInputMethodUtil()->GetHardwareLoginInputMethodIds());
if (!data->login_layouts_only) {
// Enable all the other layouts
std::vector<std::string> candidates;
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 6db7bf5..0009c9a 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -581,10 +581,13 @@ void GuestLanguageSetCallbackData::Callback(
input_method::InputMethodManager::Get();
// Active layout must be hardware "login layout".
// The previous one must be "locale default layout".
- const std::string login_input_method =
- ime_manager->GetInputMethodUtil()->GetHardwareLoginInputMethodId();
- ime_manager->ChangeInputMethod(login_input_method);
+ // First, enable all hardware input methods.
+ const std::vector<std::string>& input_methods =
+ ime_manager->GetInputMethodUtil()->GetHardwareInputMethodIds();
+ for (size_t i = 0; i < input_methods.size(); ++i)
+ ime_manager->EnableInputMethod(input_methods[i]);
+ // Second, enable locale based input methods.
const std::string locale_default_input_method =
ime_manager->GetInputMethodUtil()->
GetLanguageDefaultInputMethodId(loaded_locale);
@@ -592,7 +595,13 @@ void GuestLanguageSetCallbackData::Callback(
PrefService* user_prefs = self->profile->GetPrefs();
user_prefs->SetString(prefs::kLanguagePreviousInputMethod,
locale_default_input_method);
+ ime_manager->EnableInputMethod(locale_default_input_method);
}
+
+ // Finally, activate the first login input method.
+ const std::vector<std::string>& login_input_methods =
+ ime_manager->GetInputMethodUtil()->GetHardwareLoginInputMethodIds();
+ ime_manager->ChangeInputMethod(login_input_methods[0]);
}
void SetGuestLocale(UserManager* const usermanager, Profile* const profile) {
diff --git a/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc b/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc
index ac7c9c7..aa8506c 100644
--- a/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc
+++ b/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/extensions/extension_apitest.h"
+#include <vector>
+
#include "base/command_line.h"
#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
@@ -33,8 +35,10 @@ class SetInputMethodListener : public content::NotificationObserver {
explicit SetInputMethodListener(int count) : count_(count) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE,
content::NotificationService::AllSources());
+ std::vector<std::string> keyboard_layouts;
+ keyboard_layouts.push_back(kInitialInputMethodOnLoginScreen);
chromeos::input_method::InputMethodManager::Get()->EnableLoginLayouts(
- kLoginScreenUILanguage, kInitialInputMethodOnLoginScreen);
+ kLoginScreenUILanguage, keyboard_layouts);
}
virtual ~SetInputMethodListener() {
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 =
diff --git a/chrome/browser/chromeos/login/login_display_host_impl.cc b/chrome/browser/chromeos/login/login_display_host_impl.cc
index 20b6774..708d067 100644
--- a/chrome/browser/chromeos/login/login_display_host_impl.cc
+++ b/chrome/browser/chromeos/login/login_display_host_impl.cc
@@ -147,11 +147,17 @@ void DetermineAndSaveHardwareKeyboard(const std::string& locale,
if (!layout.empty()) {
PrefService* prefs = g_browser_process->local_state();
prefs->SetString(prefs::kHardwareKeyboardLayout, layout);
+
// This asks the file thread to save the prefs (i.e. doesn't block).
// The latest values of Local State reside in memory so we can safely
// get the value of kHardwareKeyboardLayout even if the data is not
// yet saved to disk.
prefs->CommitPendingWrite();
+
+ chromeos::input_method::InputMethodManager* manager =
+ chromeos::input_method::InputMethodManager::Get();
+ manager->GetInputMethodUtil()->UpdateHardwareLayoutCache();
+ manager->SetInputMethodLoginDefault();
}
}
@@ -1078,7 +1084,7 @@ void ShowLoginWizard(const std::string& first_screen_name) {
// 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()) {
- manager->SetInputMethodDefault();
+ manager->SetInputMethodLoginDefault();
PrefService* prefs = g_browser_process->local_state();
// Apply owner preferences for tap-to-click and mouse buttons swap for
@@ -1145,7 +1151,8 @@ void ShowLoginWizard(const std::string& first_screen_name) {
std::string locale = chromeos::StartupUtils::GetInitialLocale();
prefs->SetString(prefs::kApplicationLocale, locale);
manager->EnableLoginLayouts(
- locale, manager->GetInputMethodUtil()->GetHardwareInputMethodId());
+ locale,
+ manager->GetInputMethodUtil()->GetHardwareInputMethodIds());
base::ThreadRestrictions::ScopedAllowIO allow_io;
const std::string loaded_locale =
ResourceBundle::GetSharedInstance().ReloadLocaleResources(locale);
@@ -1169,14 +1176,18 @@ void ShowLoginWizard(const std::string& first_screen_name) {
VLOG(1) << "Current locale: " << current_locale;
std::string locale = startup_manifest->initial_locale_default();
+ std::string layout = startup_manifest->keyboard_layout();
+ VLOG(1) << "Initial locale: " << locale << "keyboard layout " << layout;
+
+ // Determine keyboard layout from OEM customization (if provided) or
+ // initial locale and save it in preferences.
+ DetermineAndSaveHardwareKeyboard(locale, layout);
+
if (!current_locale.empty() || locale.empty()) {
ShowLoginWizardFinish(first_screen_name, startup_manifest, display_host);
return;
}
- std::string layout = startup_manifest->keyboard_layout();
- VLOG(1) << "Initial locale: " << locale << "keyboard layout " << layout;
-
// Save initial locale from VPD/customization manifest as current
// Chrome locale. Otherwise it will be lost if Chrome restarts.
// Don't need to schedule pref save because setting initial local
@@ -1184,10 +1195,6 @@ void ShowLoginWizard(const std::string& first_screen_name) {
prefs->SetString(prefs::kApplicationLocale, locale);
chromeos::StartupUtils::SetInitialLocale(locale);
- // Determine keyboard layout from OEM customization (if provided) or
- // initial locale and save it in preferences.
- DetermineAndSaveHardwareKeyboard(locale, layout);
-
scoped_ptr<ShowLoginWizardSwitchLanguageCallbackData> data(
new ShowLoginWizardSwitchLanguageCallbackData(
first_screen_name, startup_manifest, display_host));
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index 67a84cd..ea4da59 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/chromeos/preferences.h"
+#include <vector>
+
#include "ash/autoclick/autoclick_controller.h"
#include "ash/magnifier/magnifier_constants.h"
#include "ash/shell.h"
@@ -87,12 +89,11 @@ void Preferences::RegisterProfilePrefs(
std::string hardware_keyboard_id;
// TODO(yusukes): Remove the runtime hack.
if (base::SysInfo::IsRunningOnChromeOS()) {
- input_method::InputMethodManager* manager =
- input_method::InputMethodManager::Get();
- if (manager) {
- hardware_keyboard_id =
- manager->GetInputMethodUtil()->GetHardwareInputMethodId();
- }
+ DCHECK(g_browser_process);
+ PrefService* local_state = g_browser_process->local_state();
+ DCHECK(local_state);
+ hardware_keyboard_id =
+ local_state->GetString(prefs::kHardwareKeyboardLayout);
} else {
hardware_keyboard_id = "xkb:us::eng"; // only for testing.
}
@@ -582,7 +583,7 @@ void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
if (section == std::string(language_prefs::kGeneralSectionName) &&
name == std::string(language_prefs::kPreloadEnginesConfigName)) {
- input_method_manager_->EnableInputMethods(split_values);
+ input_method_manager_->ReplaceEnabledInputMethods(split_values);
return;
}
}
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 7fac318..f1c03a6 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -962,7 +962,7 @@ void SigninScreenHandler::SetUserInputMethod(const std::string& username) {
DVLOG(0) << "SetUserInputMethod('" << username
<< "'): failed to set user layout. Switching to default.";
- manager->SetInputMethodDefault();
+ manager->SetInputMethodLoginDefault();
}
}
diff --git a/chromeos/ime/fake_input_method_delegate.cc b/chromeos/ime/fake_input_method_delegate.cc
index 2757750..e06e0d3 100644
--- a/chromeos/ime/fake_input_method_delegate.cc
+++ b/chromeos/ime/fake_input_method_delegate.cc
@@ -14,7 +14,7 @@ FakeInputMethodDelegate::FakeInputMethodDelegate()
FakeInputMethodDelegate::~FakeInputMethodDelegate() {
}
-std::string FakeInputMethodDelegate::GetHardwareKeyboardLayout() const {
+std::string FakeInputMethodDelegate::GetHardwareKeyboardLayouts() const {
return hardware_keyboard_layout_;
}
@@ -32,5 +32,10 @@ base::string16 FakeInputMethodDelegate::GetDisplayLanguageName(
return base::string16();
}
+void FakeInputMethodDelegate::SetHardwareKeyboardLayoutForTesting(
+ const std::string& layout) {
+ set_hardware_keyboard_layout(layout);
+}
+
} // namespace input_method
} // namespace chromeos
diff --git a/chromeos/ime/fake_input_method_delegate.h b/chromeos/ime/fake_input_method_delegate.h
index 4f1a100..0c0b385 100644
--- a/chromeos/ime/fake_input_method_delegate.h
+++ b/chromeos/ime/fake_input_method_delegate.h
@@ -5,6 +5,8 @@
#ifndef CHROMEOS_IME_FAKE_INPUT_METHOD_DELEGATE_H_
#define CHROMEOS_IME_FAKE_INPUT_METHOD_DELEGATE_H_
+#include <vector>
+
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
@@ -25,8 +27,10 @@ class CHROMEOS_EXPORT FakeInputMethodDelegate : public InputMethodDelegate {
virtual ~FakeInputMethodDelegate();
// InputMethodDelegate implementation:
- virtual std::string GetHardwareKeyboardLayout() const OVERRIDE;
+ virtual std::string GetHardwareKeyboardLayouts() const OVERRIDE;
virtual base::string16 GetLocalizedString(int resource_id) const OVERRIDE;
+ virtual void SetHardwareKeyboardLayoutForTesting(
+ const std::string& layout) OVERRIDE;
virtual base::string16 GetDisplayLanguageName(
const std::string& language_code) const OVERRIDE;
diff --git a/chromeos/ime/input_method_delegate.h b/chromeos/ime/input_method_delegate.h
index b732c48..c121d18 100644
--- a/chromeos/ime/input_method_delegate.h
+++ b/chromeos/ime/input_method_delegate.h
@@ -19,13 +19,16 @@ class InputMethodDelegate {
InputMethodDelegate() {}
virtual ~InputMethodDelegate() {}
- // Retrieves the hardware keyboard layout ID. May return an empty string if
- // the ID is unknown.
- virtual std::string GetHardwareKeyboardLayout() const = 0;
+ // Returns original VPD value.
+ virtual std::string GetHardwareKeyboardLayouts() const = 0;
// Retrieves localized string for |resource_id|.
virtual base::string16 GetLocalizedString(int resource_id) const = 0;
+ // Set hardware layout string for testting purpose.
+ virtual void SetHardwareKeyboardLayoutForTesting(
+ const std::string& layout) = 0;
+
// Converts a language code to a language display name, using the
// current application locale.
// Examples: "fi" => "Finnish"
diff --git a/chromeos/ime/input_method_manager.h b/chromeos/ime/input_method_manager.h
index c86a07e..a822a94 100644
--- a/chromeos/ime/input_method_manager.h
+++ b/chromeos/ime/input_method_manager.h
@@ -116,21 +116,22 @@ class CHROMEOS_EXPORT InputMethodManager {
// Enables "login" keyboard layouts (e.g. US Qwerty, US Dvorak, French
// Azerty) that are necessary for the |language_code| and then switches to
- // |initial_layout| if the string is not empty. For example, if
+ // |initial_layouts| if the given list is not empty. For example, if
// |language_code| is "en-US", US Qwerty, US International, US Extended, US
// Dvorak, and US Colemak layouts would be enabled. Likewise, for Germany
// locale, US Qwerty which corresponds to the hardware keyboard layout and
// several keyboard layouts for Germany would be enabled.
- // Only layouts suitable for login screen are enabled.
- virtual void EnableLoginLayouts(const std::string& language_code,
- const std::string& initial_layout) = 0;
+ // Only layouts suitable for login screen are enabled.
+ virtual void EnableLoginLayouts(
+ const std::string& language_code,
+ const std::vector<std::string>& initial_layouts) = 0;
// Activates the input method property specified by the |key|.
virtual void ActivateInputMethodProperty(const std::string& key) = 0;
// Updates the list of active input method IDs, and then starts or stops the
// system input method framework as needed.
- virtual bool EnableInputMethods(
+ virtual bool ReplaceEnabledInputMethods(
const std::vector<std::string>& new_active_input_method_ids) = 0;
// Adds one entry to the list of active input method IDs, and then starts or
@@ -153,8 +154,8 @@ class CHROMEOS_EXPORT InputMethodManager {
// Sets the list of extension IME ids which should be enabled.
virtual void SetEnabledExtensionImes(std::vector<std::string>* ids) = 0;
- // Sets current input method to default (first owners, then hardware).
- virtual void SetInputMethodDefault() = 0;
+ // Sets current input method to login default (first owners, then hardware).
+ virtual void SetInputMethodLoginDefault() = 0;
// Gets the descriptor of the input method which is currently selected.
virtual InputMethodDescriptor GetCurrentInputMethod() const = 0;