Commit e979192f authored by alemate@chromium.org's avatar alemate@chromium.org

Guest Mode: input method should default to the underlying latin keyboard layout.

Currently Guest mode always uses default value of
Preferences.PreferredInputMethod = "" (empty string) that
always leads to "us" keyboard layout (compiled-in default).

Guest sessions should have the following input methods/keyboards readily
available:
 - the VPD value (assuming the latin keyboard representing the underlying
   hardware; should be the default; e.g. French chromebook => azerty)
 - the additional input method/keyboard based on the locale (e.g. Japanese
   locale => should also add the Japanese IME; there are existing rules for
   this)


BUG=329018
TEST=unittest

Review URL: https://codereview.chromium.org/133273032

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247938 0039d316-1c4b-4281-b951-d872f2087c98
parent dda9d161
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "chrome/browser/chromeos/base/locale_util.h" #include "chrome/browser/chromeos/base/locale_util.h"
#include <vector>
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chromeos/ime/input_method_manager.h" #include "chromeos/ime/input_method_manager.h"
...@@ -18,16 +20,19 @@ namespace { ...@@ -18,16 +20,19 @@ namespace {
struct SwitchLanguageData { struct SwitchLanguageData {
SwitchLanguageData(const std::string& locale, SwitchLanguageData(const std::string& locale,
const bool enableLocaleKeyboardLayouts, const bool enableLocaleKeyboardLayouts,
const bool login_layouts_only,
scoped_ptr<locale_util::SwitchLanguageCallback> callback) scoped_ptr<locale_util::SwitchLanguageCallback> callback)
: callback(callback.Pass()), : callback(callback.Pass()),
locale(locale), locale(locale),
enableLocaleKeyboardLayouts(enableLocaleKeyboardLayouts), enableLocaleKeyboardLayouts(enableLocaleKeyboardLayouts),
login_layouts_only(login_layouts_only),
success(false) {} success(false) {}
scoped_ptr<locale_util::SwitchLanguageCallback> callback; scoped_ptr<locale_util::SwitchLanguageCallback> callback;
const std::string locale; const std::string locale;
const bool enableLocaleKeyboardLayouts; const bool enableLocaleKeyboardLayouts;
const bool login_layouts_only;
std::string loaded_locale; std::string loaded_locale;
bool success; bool success;
}; };
...@@ -58,9 +63,21 @@ void FinishSwitchLanguage(scoped_ptr<SwitchLanguageData> data) { ...@@ -58,9 +63,21 @@ void FinishSwitchLanguage(scoped_ptr<SwitchLanguageData> data) {
// use may not be supported by the new locale (3rd parameter). // use may not be supported by the new locale (3rd parameter).
input_method::InputMethodManager* manager = input_method::InputMethodManager* manager =
input_method::InputMethodManager::Get(); input_method::InputMethodManager::Get();
manager->EnableLayouts( manager->EnableLoginLayouts(
data->locale, data->locale,
manager->GetInputMethodUtil()->GetHardwareInputMethodId()); manager->GetInputMethodUtil()->GetHardwareLoginInputMethodId());
if (!data->login_layouts_only) {
// Enable all the other layouts
std::vector<std::string> candidates;
input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
// Add input methods associated with the language.
util->GetInputMethodIdsFromLanguageCode(
data->locale, input_method::kKeyboardLayoutsOnly, &candidates);
for (std::vector<std::string>::const_iterator i = candidates.begin();
i != candidates.end();
++i)
manager->EnableInputMethod(*i);
}
} }
} }
gfx::PlatformFontPango::ReloadDefaultFont(); gfx::PlatformFontPango::ReloadDefaultFont();
...@@ -73,11 +90,15 @@ void FinishSwitchLanguage(scoped_ptr<SwitchLanguageData> data) { ...@@ -73,11 +90,15 @@ void FinishSwitchLanguage(scoped_ptr<SwitchLanguageData> data) {
namespace locale_util { namespace locale_util {
void SwitchLanguage(const std::string& locale, void SwitchLanguage(const std::string& locale,
bool enableLocaleKeyboardLayouts, const bool enableLocaleKeyboardLayouts,
const bool login_layouts_only,
scoped_ptr<SwitchLanguageCallback> callback) { scoped_ptr<SwitchLanguageCallback> callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
scoped_ptr<SwitchLanguageData> data(new SwitchLanguageData( scoped_ptr<SwitchLanguageData> data(
locale, enableLocaleKeyboardLayouts, callback.Pass())); new SwitchLanguageData(locale,
enableLocaleKeyboardLayouts,
login_layouts_only,
callback.Pass()));
base::Closure reloader( base::Closure reloader(
base::Bind(&SwitchLanguageDoReloadLocale, base::Unretained(data.get()))); base::Bind(&SwitchLanguageDoReloadLocale, base::Unretained(data.get())));
content::BrowserThread::PostBlockingPoolTaskAndReply( content::BrowserThread::PostBlockingPoolTaskAndReply(
......
...@@ -37,8 +37,10 @@ typedef base::Callback<void(const std::string&, const std::string&, bool)> ...@@ -37,8 +37,10 @@ typedef base::Callback<void(const std::string&, const std::string&, bool)>
// method currently in use may not be supported by the new locale. (i.e. // method currently in use may not be supported by the new locale. (i.e.
// using new locale with unsupported input method may lead to undefined // using new locale with unsupported input method may lead to undefined
// behavior; use "enableLocaleKeyboardLayouts=false" with caution) // behavior; use "enableLocaleKeyboardLayouts=false" with caution)
// Note2: login_layouts_only=true enables only login-capable layouts.
void SwitchLanguage(const std::string& locale, void SwitchLanguage(const std::string& locale,
bool enableLocaleKeyboardLayouts, const bool enableLocaleKeyboardLayouts,
const bool login_layouts_only,
scoped_ptr<SwitchLanguageCallback> callback); scoped_ptr<SwitchLanguageCallback> callback);
} // namespace locale_util } // namespace locale_util
......
...@@ -36,9 +36,11 @@ ...@@ -36,9 +36,11 @@
#include "chrome/browser/chromeos/external_metrics.h" #include "chrome/browser/chromeos/external_metrics.h"
#include "chrome/browser/chromeos/imageburner/burn_manager.h" #include "chrome/browser/chromeos/imageburner/burn_manager.h"
#include "chrome/browser/chromeos/input_method/input_method_configuration.h" #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h" #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h"
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h" #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h"
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
#include "chrome/browser/chromeos/language_preferences.h"
#include "chrome/browser/chromeos/login/authenticator.h" #include "chrome/browser/chromeos/login/authenticator.h"
#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/login_wizard.h" #include "chrome/browser/chromeos/login/login_wizard.h"
...@@ -553,6 +555,54 @@ void ChromeBrowserMainPartsChromeos::PreProfileInit() { ...@@ -553,6 +555,54 @@ void ChromeBrowserMainPartsChromeos::PreProfileInit() {
} }
} }
class GuestLanguageSetCallbackData {
public:
explicit GuestLanguageSetCallbackData(Profile* profile) : profile(profile) {
}
// Must match SwitchLanguageCallback type.
static void Callback(const scoped_ptr<GuestLanguageSetCallbackData>& self,
const std::string& locale,
const std::string& loaded_locale,
bool success);
Profile* profile;
};
// static
void GuestLanguageSetCallbackData::Callback(
const scoped_ptr<GuestLanguageSetCallbackData>& self,
const std::string& locale,
const std::string& loaded_locale,
bool success) {
input_method::InputMethodManager* const ime_manager =
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);
const std::string locale_default_input_method =
ime_manager->GetInputMethodUtil()->
GetLanguageDefaultInputMethodId(loaded_locale);
if (!locale_default_input_method.empty()) {
PrefService* user_prefs = self->profile->GetPrefs();
user_prefs->SetString(prefs::kLanguagePreviousInputMethod,
locale_default_input_method);
}
}
void SetGuestLocale(UserManager* const usermanager, Profile* const profile) {
scoped_ptr<GuestLanguageSetCallbackData> data(
new GuestLanguageSetCallbackData(profile));
scoped_ptr<locale_util::SwitchLanguageCallback> callback(
new locale_util::SwitchLanguageCallback(base::Bind(
&GuestLanguageSetCallbackData::Callback, base::Passed(data.Pass()))));
User* const user = usermanager->GetUserByProfile(profile);
usermanager->RespectLocalePreference(profile, user, callback.Pass());
}
void ChromeBrowserMainPartsChromeos::PostProfileInit() { void ChromeBrowserMainPartsChromeos::PostProfileInit() {
// -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun() // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
// -- just after CreateProfile(). // -- just after CreateProfile().
...@@ -609,6 +659,12 @@ void ChromeBrowserMainPartsChromeos::PostProfileInit() { ...@@ -609,6 +659,12 @@ void ChromeBrowserMainPartsChromeos::PostProfileInit() {
OptionallyRunChromeOSLoginManager(parsed_command_line(), profile()); OptionallyRunChromeOSLoginManager(parsed_command_line(), profile());
} }
// Guest user profile is never initialized with locale settings,
// so we need special handling for Guest session.
UserManager* const usermanager = UserManager::Get();
if (usermanager->IsLoggedInAsGuest())
SetGuestLocale(usermanager, profile());
// These observers must be initialized after the profile because // These observers must be initialized after the profile because
// they use the profile to dispatch extension events. // they use the profile to dispatch extension events.
extension_system_event_observer_.reset(new ExtensionSystemEventObserver()); extension_system_event_observer_.reset(new ExtensionSystemEventObserver());
......
...@@ -33,8 +33,8 @@ class SetInputMethodListener : public content::NotificationObserver { ...@@ -33,8 +33,8 @@ class SetInputMethodListener : public content::NotificationObserver {
explicit SetInputMethodListener(int count) : count_(count) { explicit SetInputMethodListener(int count) : count_(count) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE, registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE,
content::NotificationService::AllSources()); content::NotificationService::AllSources());
chromeos::input_method::InputMethodManager::Get()-> chromeos::input_method::InputMethodManager::Get()->EnableLoginLayouts(
EnableLayouts(kLoginScreenUILanguage, kInitialInputMethodOnLoginScreen); kLoginScreenUILanguage, kInitialInputMethodOnLoginScreen);
} }
virtual ~SetInputMethodListener() { virtual ~SetInputMethodListener() {
......
...@@ -43,9 +43,7 @@ bool Contains(const std::vector<std::string>& container, ...@@ -43,9 +43,7 @@ bool Contains(const std::vector<std::string>& container,
bool InputMethodManagerImpl::IsLoginKeyboard( bool InputMethodManagerImpl::IsLoginKeyboard(
const std::string& layout) const { const std::string& layout) const {
const InputMethodDescriptor* ime = return util_.IsLoginKeyboard(layout);
util_.GetInputMethodDescriptorFromId(layout);
return ime ? ime->is_login_keyboard() : false;
} }
InputMethodManagerImpl::InputMethodManagerImpl( InputMethodManagerImpl::InputMethodManagerImpl(
...@@ -159,8 +157,9 @@ const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId( ...@@ -159,8 +157,9 @@ const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId(
return ime; return ime;
} }
void InputMethodManagerImpl::EnableLayouts(const std::string& language_code, void InputMethodManagerImpl::EnableLoginLayouts(
const std::string& initial_layout) { const std::string& language_code,
const std::string& initial_layout) {
if (state_ == STATE_TERMINATING) if (state_ == STATE_TERMINATING)
return; return;
...@@ -171,17 +170,22 @@ void InputMethodManagerImpl::EnableLayouts(const std::string& language_code, ...@@ -171,17 +170,22 @@ void InputMethodManagerImpl::EnableLayouts(const std::string& language_code,
&candidates); &candidates);
// Add the hardware keyboard as well. We should always add this so users // 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. // can use the hardware keyboard on the login screen and the screen locker.
candidates.push_back(util_.GetHardwareInputMethodId()); candidates.push_back(util_.GetHardwareLoginInputMethodId());
std::vector<std::string> layouts; std::vector<std::string> layouts;
// First, add the initial input method ID, if it's requested, to // First, add the initial input method ID, if it's requested, to
// layouts, so it appears first on the list of active input // layouts, so it appears first on the list of active input
// methods at the input language status menu. // methods at the input language status menu.
if (util_.IsValidInputMethodId(initial_layout) && if (util_.IsValidInputMethodId(initial_layout)) {
IsLoginKeyboard(initial_layout)) { if (!IsLoginKeyboard(initial_layout)) {
layouts.push_back(initial_layout); DVLOG(1)
<< "EnableLoginLayouts: ignoring non-login initial keyboard layout:"
<< initial_layout;
} else {
layouts.push_back(initial_layout);
}
} else if (!initial_layout.empty()) { } else if (!initial_layout.empty()) {
DVLOG(1) << "EnableLayouts: ignoring non-keyboard or invalid ID: " DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: "
<< initial_layout; << initial_layout;
} }
...@@ -550,7 +554,7 @@ void InputMethodManagerImpl::SetInputMethodDefault() { ...@@ -550,7 +554,7 @@ void InputMethodManagerImpl::SetInputMethodDefault() {
initial_input_method_id = initial_input_method_id =
GetInputMethodUtil()->GetHardwareInputMethodId(); GetInputMethodUtil()->GetHardwareInputMethodId();
} }
EnableLayouts(locale, initial_input_method_id); EnableLoginLayouts(locale, initial_input_method_id);
} }
} }
......
...@@ -59,8 +59,8 @@ class InputMethodManagerImpl : public InputMethodManager, ...@@ -59,8 +59,8 @@ class InputMethodManagerImpl : public InputMethodManager,
virtual size_t GetNumActiveInputMethods() const OVERRIDE; virtual size_t GetNumActiveInputMethods() const OVERRIDE;
virtual const InputMethodDescriptor* GetInputMethodFromId( virtual const InputMethodDescriptor* GetInputMethodFromId(
const std::string& input_method_id) const OVERRIDE; const std::string& input_method_id) const OVERRIDE;
virtual void EnableLayouts(const std::string& language_code, virtual void EnableLoginLayouts(const std::string& language_code,
const std::string& initial_layout) OVERRIDE; const std::string& initial_layout) OVERRIDE;
virtual bool EnableInputMethods( virtual bool EnableInputMethods(
const std::vector<std::string>& new_active_input_method_ids) OVERRIDE; const std::vector<std::string>& new_active_input_method_ids) OVERRIDE;
virtual bool EnableInputMethod(const std::string& new_active_input_method_id) virtual bool EnableInputMethod(const std::string& new_active_input_method_id)
......
...@@ -237,7 +237,7 @@ TEST_F(InputMethodManagerImplTest, TestObserver) { ...@@ -237,7 +237,7 @@ TEST_F(InputMethodManagerImplTest, TestObserver) {
InitComponentExtension(); InitComponentExtension();
manager_->AddObserver(&observer); manager_->AddObserver(&observer);
EXPECT_EQ(0, observer.input_method_changed_count_); EXPECT_EQ(0, observer.input_method_changed_count_);
manager_->EnableLayouts("en-US", "xkb:us::eng"); manager_->EnableLoginLayouts("en-US", "xkb:us::eng");
EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(1, observer.input_method_changed_count_);
EXPECT_EQ(1, observer.input_method_property_changed_count_); EXPECT_EQ(1, observer.input_method_property_changed_count_);
manager_->ChangeInputMethod("xkb:us:dvorak:eng"); manager_->ChangeInputMethod("xkb:us:dvorak:eng");
...@@ -284,20 +284,20 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayouts) { ...@@ -284,20 +284,20 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayouts) {
// Currently 5 keyboard layouts are supported for en-US, and 1 for ja. See // Currently 5 keyboard layouts are supported for en-US, and 1 for ja. See
// ibus_input_method.txt. // ibus_input_method.txt.
InitComponentExtension(); InitComponentExtension();
manager_->EnableLayouts("en-US", ""); manager_->EnableLoginLayouts("en-US", "");
EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
for (size_t i = 0; i < manager_->GetActiveInputMethodIds().size(); ++i) for (size_t i = 0; i < manager_->GetActiveInputMethodIds().size(); ++i)
LOG(ERROR) << manager_->GetActiveInputMethodIds().at(i); LOG(ERROR) << manager_->GetActiveInputMethodIds().at(i);
// For http://crbug.com/19655#c11 - (5) // For http://crbug.com/19655#c11 - (5)
// The hardware keyboard layout "xkb:us::eng" is always active, hence 2U. // The hardware keyboard layout "xkb:us::eng" is always active, hence 2U.
manager_->EnableLayouts("ja", ""); // Japanese manager_->EnableLoginLayouts("ja", ""); // Japanese
EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
} }
TEST_F(InputMethodManagerImplTest, TestEnableLayoutsAndCurrentInputMethod) { TEST_F(InputMethodManagerImplTest, TestEnableLayoutsAndCurrentInputMethod) {
// For http://crbug.com/329061 // For http://crbug.com/329061
manager_->EnableLayouts("en-US", "xkb:se::swe"); manager_->EnableLoginLayouts("en-US", "xkb:se::swe");
const std::string im_id = manager_->GetCurrentInputMethod().id(); const std::string im_id = manager_->GetCurrentInputMethod().id();
EXPECT_EQ("xkb:se::swe", im_id); EXPECT_EQ("xkb:se::swe", im_id);
} }
...@@ -305,17 +305,24 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutsAndCurrentInputMethod) { ...@@ -305,17 +305,24 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutsAndCurrentInputMethod) {
TEST_F(InputMethodManagerImplTest, TestEnableLayoutsNonUsHardwareKeyboard) { TEST_F(InputMethodManagerImplTest, TestEnableLayoutsNonUsHardwareKeyboard) {
// The physical layout is French. // The physical layout is French.
delegate_->set_hardware_keyboard_layout("xkb:fr::fra"); delegate_->set_hardware_keyboard_layout("xkb:fr::fra");
manager_->EnableLayouts("en-US", ""); manager_->EnableLoginLayouts("en-US", "");
EXPECT_EQ(6U, manager_->GetNumActiveInputMethods()); // 5 + French EXPECT_EQ(6U, manager_->GetNumActiveInputMethods()); // 5 + French
// The physical layout is Japanese. // The physical layout is Japanese.
delegate_->set_hardware_keyboard_layout("xkb:jp::jpn"); delegate_->set_hardware_keyboard_layout("xkb:jp::jpn");
manager_->EnableLayouts("ja", ""); manager_->EnableLoginLayouts("ja", "");
// "xkb:us::eng" is not needed, hence 1. // "xkb:us::eng" is not needed, hence 1.
EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
// The physical layout is Russian.
delegate_->set_hardware_keyboard_layout("xkb:ru::rus");
manager_->EnableLoginLayouts("ru", "");
// "xkb:us::eng" only.
EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
EXPECT_EQ("xkb:us::eng", manager_->GetActiveInputMethodIds().front());
} }
TEST_F(InputMethodManagerImplTest, TestActiveInputMethods) { TEST_F(InputMethodManagerImplTest, TestActiveInputMethods) {
manager_->EnableLayouts("ja", ""); // Japanese manager_->EnableLoginLayouts("ja", ""); // Japanese
EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
scoped_ptr<InputMethodDescriptors> methods( scoped_ptr<InputMethodDescriptors> methods(
manager_->GetActiveInputMethods()); manager_->GetActiveInputMethods());
...@@ -670,7 +677,7 @@ TEST_F(InputMethodManagerImplTest, TestNextInputMethod) { ...@@ -670,7 +677,7 @@ TEST_F(InputMethodManagerImplTest, TestNextInputMethod) {
manager_->AddObserver(&observer); manager_->AddObserver(&observer);
InitComponentExtension(); InitComponentExtension();
// For http://crbug.com/19655#c11 - (1) // For http://crbug.com/19655#c11 - (1)
manager_->EnableLayouts("en-US", "xkb:us::eng"); manager_->EnableLoginLayouts("en-US", "xkb:us::eng");
EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
EXPECT_EQ("us", xkeyboard_->last_layout_); EXPECT_EQ("us", xkeyboard_->last_layout_);
...@@ -708,7 +715,7 @@ TEST_F(InputMethodManagerImplTest, TestPreviousInputMethod) { ...@@ -708,7 +715,7 @@ TEST_F(InputMethodManagerImplTest, TestPreviousInputMethod) {
ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
keyup_accelerator.set_type(ui::ET_KEY_RELEASED); keyup_accelerator.set_type(ui::ET_KEY_RELEASED);
manager_->EnableLayouts("en-US", "xkb:us::eng"); manager_->EnableLoginLayouts("en-US", "xkb:us::eng");
EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
EXPECT_EQ("us", xkeyboard_->last_layout_); EXPECT_EQ("us", xkeyboard_->last_layout_);
...@@ -781,7 +788,7 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithUsLayouts) { ...@@ -781,7 +788,7 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithUsLayouts) {
TestObserver observer; TestObserver observer;
manager_->AddObserver(&observer); manager_->AddObserver(&observer);
InitComponentExtension(); InitComponentExtension();
manager_->EnableLayouts("en-US", "xkb:us::eng"); manager_->EnableLoginLayouts("en-US", "xkb:us::eng");
EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
EXPECT_EQ("us", xkeyboard_->last_layout_); EXPECT_EQ("us", xkeyboard_->last_layout_);
...@@ -818,7 +825,7 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpLayout) { ...@@ -818,7 +825,7 @@ TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpLayout) {
ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
keyup_accelerator.set_type(ui::ET_KEY_RELEASED); keyup_accelerator.set_type(ui::ET_KEY_RELEASED);
manager_->EnableLayouts("ja", "xkb:us::eng"); manager_->EnableLoginLayouts("ja", "xkb:us::eng");
EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
EXPECT_EQ("us", xkeyboard_->last_layout_); EXPECT_EQ("us", xkeyboard_->last_layout_);
......
...@@ -603,6 +603,17 @@ void InputMethodUtil::GetLanguageCodesFromInputMethodIds( ...@@ -603,6 +603,17 @@ void InputMethodUtil::GetLanguageCodesFromInputMethodIds(
} }
} }
std::string InputMethodUtil::GetLanguageDefaultInputMethodId(
const std::string& language_code) {
std::vector<std::string> candidates;
GetInputMethodIdsFromLanguageCode(
language_code, input_method::kKeyboardLayoutsOnly, &candidates);
if (candidates.size())
return candidates.front();
return std::string();
}
std::string InputMethodUtil::GetHardwareInputMethodId() const { std::string InputMethodUtil::GetHardwareInputMethodId() const {
const std::string input_method_id = delegate_->GetHardwareKeyboardLayout(); const std::string input_method_id = delegate_->GetHardwareKeyboardLayout();
...@@ -615,6 +626,22 @@ std::string InputMethodUtil::GetHardwareInputMethodId() const { ...@@ -615,6 +626,22 @@ std::string InputMethodUtil::GetHardwareInputMethodId() const {
return input_method_id; return input_method_id;
} }
std::string InputMethodUtil::GetHardwareLoginInputMethodId() const {
const std::string input_method_id = GetHardwareInputMethodId();
if (!IsLoginKeyboard(input_method_id))
return GetFallbackInputMethodDescriptor().id();
return input_method_id;
}
bool InputMethodUtil::IsLoginKeyboard(const std::string& input_method_id)
const {
const InputMethodDescriptor* ime =
GetInputMethodDescriptorFromId(input_method_id);
return ime ? ime->is_login_keyboard() : false;
}
void InputMethodUtil::SetComponentExtensions( void InputMethodUtil::SetComponentExtensions(
const InputMethodDescriptors& imes) { const InputMethodDescriptors& imes) {
component_extension_ime_id_to_descriptor_.clear(); component_extension_ime_id_to_descriptor_.clear();
......
...@@ -93,10 +93,20 @@ class InputMethodUtil { ...@@ -93,10 +93,20 @@ class InputMethodUtil {
const std::vector<std::string>& input_method_ids, const std::vector<std::string>& input_method_ids,
std::vector<std::string>* out_language_codes) const; std::vector<std::string>* out_language_codes) const;
// Gets first input method associated with the language.
// 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" // Returns the input method ID of the hardware keyboard. e.g. "xkb:us::eng"
// for the US Qwerty keyboard. // for the US Qwerty keyboard.
std::string GetHardwareInputMethodId() const; std::string GetHardwareInputMethodId() const;
// Returns the login-allowed input method ID of the hardware keyboard.
std::string GetHardwareLoginInputMethodId() const;
// Returns true if given input method can be used to input login data.
bool IsLoginKeyboard(const std::string& input_method_id) const;
// Returns true if the given input method id is supported. // Returns true if the given input method id is supported.
bool IsValidInputMethodId(const std::string& input_method_id) const; bool IsValidInputMethodId(const std::string& input_method_id) const;
......
...@@ -72,8 +72,9 @@ const InputMethodDescriptor* MockInputMethodManager::GetInputMethodFromId( ...@@ -72,8 +72,9 @@ const InputMethodDescriptor* MockInputMethodManager::GetInputMethodFromId(
return NULL; return NULL;
} }
void MockInputMethodManager::EnableLayouts(const std::string& language_code, void MockInputMethodManager::EnableLoginLayouts(
const std::string& initial_layout) { const std::string& language_code,
const std::string& initial_layout) {
} }
bool MockInputMethodManager::EnableInputMethods( bool MockInputMethodManager::EnableInputMethods(
......
...@@ -36,8 +36,8 @@ class MockInputMethodManager : public InputMethodManager { ...@@ -36,8 +36,8 @@ class MockInputMethodManager : public InputMethodManager {
virtual size_t GetNumActiveInputMethods() const OVERRIDE; virtual size_t GetNumActiveInputMethods() const OVERRIDE;
virtual const InputMethodDescriptor* GetInputMethodFromId( virtual const InputMethodDescriptor* GetInputMethodFromId(
const std::string& input_method_id) const OVERRIDE; const std::string& input_method_id) const OVERRIDE;
virtual void EnableLayouts(const std::string& language_code, virtual void EnableLoginLayouts(const std::string& language_code,
const std::string& initial_layout) OVERRIDE; const std::string& initial_layout) OVERRIDE;
virtual bool EnableInputMethods( virtual bool EnableInputMethods(
const std::vector<std::string>& new_active_input_method_ids) OVERRIDE; const std::vector<std::string>& new_active_input_method_ids) OVERRIDE;
virtual bool EnableInputMethod( virtual bool EnableInputMethod(
......
...@@ -126,7 +126,7 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, Bounds) { ...@@ -126,7 +126,7 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, Bounds) {
ASSERT_TRUE(imm); ASSERT_TRUE(imm);
// Add keyboard layouts to enable the mode indicator. // Add keyboard layouts to enable the mode indicator.
imm->EnableLayouts("fr", "xkb:fr::fra"); imm->EnableLoginLayouts("fr", "xkb:fr::fra");
ASSERT_LT(1UL, imm->GetNumActiveInputMethods()); ASSERT_LT(1UL, imm->GetNumActiveInputMethods());
chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window = chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window =
...@@ -190,7 +190,7 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, NumOfWidgets) { ...@@ -190,7 +190,7 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, NumOfWidgets) {
ASSERT_TRUE(imm); ASSERT_TRUE(imm);
// Add keyboard layouts to enable the mode indicator. // Add keyboard layouts to enable the mode indicator.
imm->EnableLayouts("fr", "xkb:fr::fra"); imm->EnableLoginLayouts("fr", "xkb:fr::fra");
ASSERT_LT(1UL, imm->GetNumActiveInputMethods()); ASSERT_LT(1UL, imm->GetNumActiveInputMethods());
chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window = chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window =
......
...@@ -1137,9 +1137,8 @@ void ShowLoginWizard(const std::string& first_screen_name) { ...@@ -1137,9 +1137,8 @@ void ShowLoginWizard(const std::string& first_screen_name) {
if (!prefs->HasPrefPath(prefs::kApplicationLocale)) { if (!prefs->HasPrefPath(prefs::kApplicationLocale)) {
std::string locale = chromeos::StartupUtils::GetInitialLocale(); std::string locale = chromeos::StartupUtils::GetInitialLocale();
prefs->SetString(prefs::kApplicationLocale, locale); prefs->SetString(prefs::kApplicationLocale, locale);
manager->EnableLayouts( manager->EnableLoginLayouts(
locale, locale, manager->GetInputMethodUtil()->GetHardwareInputMethodId());
manager->GetInputMethodUtil()->GetHardwareInputMethodId());
base::ThreadRestrictions::ScopedAllowIO allow_io; base::ThreadRestrictions::ScopedAllowIO allow_io;
const std::string loaded_locale = const std::string loaded_locale =
ResourceBundle::GetSharedInstance().ReloadLocaleResources(locale); ResourceBundle::GetSharedInstance().ReloadLocaleResources(locale);
...@@ -1182,10 +1181,6 @@ void ShowLoginWizard(const std::string& first_screen_name) { ...@@ -1182,10 +1181,6 @@ void ShowLoginWizard(const std::string& first_screen_name) {
// initial locale and save it in preferences. // initial locale and save it in preferences.
DetermineAndSaveHardwareKeyboard(locale, layout); DetermineAndSaveHardwareKeyboard(locale, layout);
// Then, enable the hardware keyboard.
manager->EnableLayouts(
locale, manager->GetInputMethodUtil()->GetHardwareInputMethodId());
scoped_ptr<ShowLoginWizardSwitchLanguageCallbackData> data( scoped_ptr<ShowLoginWizardSwitchLanguageCallbackData> data(
new ShowLoginWizardSwitchLanguageCallbackData( new ShowLoginWizardSwitchLanguageCallbackData(
first_screen_name, startup_manifest, display_host)); first_screen_name, startup_manifest, display_host));
...@@ -1194,8 +1189,9 @@ void ShowLoginWizard(const std::string& first_screen_name) { ...@@ -1194,8 +1189,9 @@ void ShowLoginWizard(const std::string& first_screen_name) {
new locale_util::SwitchLanguageCallback( new locale_util::SwitchLanguageCallback(
base::Bind(&OnLanguageSwitchedCallback, base::Passed(data.Pass())))); base::Bind(&OnLanguageSwitchedCallback, base::Passed(data.Pass()))));
// Do not load locale keyboards here. // Load locale keyboards here. Hardware layout would be automatically enabled.
locale_util::SwitchLanguage(locale, false, callback.Pass()); locale_util::SwitchLanguage(
locale, true, true /* login_layouts_only */, callback.Pass());
} }
} // namespace chromeos } // namespace chromeos
...@@ -839,13 +839,21 @@ bool UserManagerImpl::RespectLocalePreference( ...@@ -839,13 +839,21 @@ bool UserManagerImpl::RespectLocalePreference(
: (std::string("account_locale - unused. "))) : (std::string("account_locale - unused. ")))
<< " Selected '" << pref_locale << "'"; << " Selected '" << pref_locale << "'";
profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN); profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
// Here we don't enable keyboard layouts. Input methods are set up when
// the user first logs in. Then the user may customize the input methods. // Here we don't enable keyboard layouts for normal users. Input methods
// Hence changing input methods here, just because the user's UI language // are set up when the user first logs in. Then the user may customize the
// is different from the login screen UI language, is not desirable. Note // input methods. Hence changing input methods here, just because the user's
// that input method preferences are synced, so users can use their // UI language is different from the login screen UI language, is not
// farovite input methods as soon as the preferences are synced. // desirable. Note that input method preferences are synced, so users can use
locale_util::SwitchLanguage(pref_locale, false, callback.Pass()); // their farovite input methods as soon as the preferences are synced.
//
// For Guest mode, user locale preferences will never get initialized.
// So input methods should be enabled somewhere.
const bool enable_layouts = UserManager::Get()->IsLoggedInAsGuest();
locale_util::SwitchLanguage(pref_locale,
enable_layouts,
false /* login_layouts_only */,
callback.Pass());
return true; return true;
} }
......
...@@ -109,7 +109,7 @@ void RunSwitchLanguageTest(const std::string& locale, ...@@ -109,7 +109,7 @@ void RunSwitchLanguageTest(const std::string& locale,
scoped_ptr<locale_util::SwitchLanguageCallback> callback( scoped_ptr<locale_util::SwitchLanguageCallback> callback(
new locale_util::SwitchLanguageCallback( new locale_util::SwitchLanguageCallback(
base::Bind(&OnLocaleSwitched, base::Unretained(&data)))); base::Bind(&OnLocaleSwitched, base::Unretained(&data))));
locale_util::SwitchLanguage(locale, true, callback.Pass()); locale_util::SwitchLanguage(locale, true, false, callback.Pass());
// Token writing moves control to BlockingPool and back. // Token writing moves control to BlockingPool and back.
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
......
...@@ -208,7 +208,10 @@ void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) { ...@@ -208,7 +208,10 @@ void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) {
new locale_util::SwitchLanguageCallback( new locale_util::SwitchLanguageCallback(
base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback, base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback,
base::Passed(callback_data.Pass())))); base::Passed(callback_data.Pass()))));
locale_util::SwitchLanguage(locale, true, callback.Pass()); locale_util::SwitchLanguage(locale,
true /* enableLocaleKeyboardLayouts */,
true /* login_layouts_only */,
callback.Pass());
} }
void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) { void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) {
......
...@@ -114,16 +114,16 @@ class CHROMEOS_EXPORT InputMethodManager { ...@@ -114,16 +114,16 @@ class CHROMEOS_EXPORT InputMethodManager {
// is not active, switch to the first one in the active input method list. // is not active, switch to the first one in the active input method list.
virtual void ChangeInputMethod(const std::string& input_method_id) = 0; virtual void ChangeInputMethod(const std::string& input_method_id) = 0;
// Enables keyboard layouts (e.g. US Qwerty, US Dvorak, French Azerty) that // Enables "login" keyboard layouts (e.g. US Qwerty, US Dvorak, French
// are necessary for the |language_code| and then switches to |initial_layout| // Azerty) that are necessary for the |language_code| and then switches to
// if the string is not empty. For example, if |language_code| is "en-US", US // |initial_layout| if the string is not empty. For example, if
// Qwerty, US International, US Extended, US Dvorak, and US Colemak layouts // |language_code| is "en-US", US Qwerty, US International, US Extended, US
// would be enabled. Likewise, for Germany locale, US Qwerty which corresponds // Dvorak, and US Colemak layouts would be enabled. Likewise, for Germany
// to the hardware keyboard layout and several keyboard layouts for Germany // locale, US Qwerty which corresponds to the hardware keyboard layout and
// would be enabled. // several keyboard layouts for Germany would be enabled.
// This method is for setting up i18n keyboard layouts for the login screen. // Only layouts suitable for login screen are enabled.
virtual void EnableLayouts(const std::string& language_code, virtual void EnableLoginLayouts(const std::string& language_code,
const std::string& initial_layout) = 0; const std::string& initial_layout) = 0;
// Activates the input method property specified by the |key|. // Activates the input method property specified by the |key|.
virtual void ActivateInputMethodProperty(const std::string& key) = 0; virtual void ActivateInputMethodProperty(const std::string& key) = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment