diff options
author | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 04:57:50 +0000 |
---|---|---|
committer | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 04:57:50 +0000 |
commit | 63cd30f5d6354a5b3008530cb3aaaf72ef60f053 (patch) | |
tree | f308aaffcb6edd1807d7c9010a7d8b5578329023 | |
parent | 756cb446d4c51569dac43bee6e3020007cc064f0 (diff) | |
download | chromium_src-63cd30f5d6354a5b3008530cb3aaaf72ef60f053.zip chromium_src-63cd30f5d6354a5b3008530cb3aaaf72ef60f053.tar.gz chromium_src-63cd30f5d6354a5b3008530cb3aaaf72ef60f053.tar.bz2 |
Implement keyboard layout switching on the login screen.
- login/user_manager.cc
Register a new Local State item, "PreferredKeyboardLayout".
- login/wizard_controller.cc
Set up keyboards for the current locale. For example, when |locale| is "en-US", enable US qwerty and US dvorak keyboard layouts.
- login/language_switch_menu.cc
Enable the keyboard layouts that are necessary for the new locale.
- login/account_screen.h
When the account creation screen is shown, enable input methods (e.g. Chinese, Japanese, Korean) so that users could input their first and last names. Disable them when the screen is closed.
- status/language_menu_button.cc
Update the Locale State when a user switches keyboard layout.
BUG=chromium-os:2619
TEST=manual & the browser_tests
Review URL: http://codereview.chromium.org/2806026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51340 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 105 insertions, 14 deletions
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc index b9cf9f1..a9affc2 100644 --- a/chrome/browser/browser_prefs.cc +++ b/chrome/browser/browser_prefs.cc @@ -58,6 +58,7 @@ #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/preferences.h" +#include "chrome/browser/chromeos/status/language_menu_button.h" #endif namespace browser { @@ -92,6 +93,7 @@ void RegisterLocalState(PrefService* local_state) { #if defined(OS_CHROMEOS) chromeos::UserManager::RegisterPrefs(local_state); WizardController::RegisterPrefs(local_state); + chromeos::LanguageMenuButton::RegisterPrefs(local_state); #endif } diff --git a/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc b/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc index 74626c7..60cf3fb 100644 --- a/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc +++ b/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc @@ -168,6 +168,10 @@ void CrosInProcessBrowserTest::SetInputMethodLibraryStatusAreaExpectations() { .Times(AnyNumber()) .WillRepeatedly(InvokeWithoutArgs(CreateFallbackInputMethodDescriptors)) .RetiresOnSaturation(); + EXPECT_CALL(*mock_input_method_library_, GetSupportedInputMethods()) + .Times(AnyNumber()) + .WillRepeatedly(InvokeWithoutArgs(CreateFallbackInputMethodDescriptors)) + .RetiresOnSaturation(); EXPECT_CALL(*mock_input_method_library_, current_ime_properties()) .Times(1) .WillOnce((ReturnRef(ime_properties_))) diff --git a/chrome/browser/chromeos/language_preferences.h b/chrome/browser/chromeos/language_preferences.h index 93a266f..f9244d4 100644 --- a/chrome/browser/chromeos/language_preferences.h +++ b/chrome/browser/chromeos/language_preferences.h @@ -393,6 +393,10 @@ const size_t kNumMozcIntegerPrefs = ARRAYSIZE_UNSAFE(kMozcIntegerPrefs); // For Traditional Chinese input methods (ibus-pinyin-bopomofo and ibus-chewing) // TODO(yusukes): Add constants for Traditional Chinese input methods. +// A string Chrome preference (Local State) of the preferred keyboard layout in +// the login screen. +const wchar_t kPreferredKeyboardLayout[] = L"PreferredKeyboardLayout"; + // A input method name that corresponds the hardware keyboard layout. // TODO(yusukes): just assuming US qwerty keyboard is not always correct. const char kHardwareKeyboardLayout[] = "xkb:us::eng"; diff --git a/chrome/browser/chromeos/login/account_screen.cc b/chrome/browser/chromeos/login/account_screen.cc index c8145a36..b9ad26d 100644 --- a/chrome/browser/chromeos/login/account_screen.cc +++ b/chrome/browser/chromeos/login/account_screen.cc @@ -5,6 +5,8 @@ #include "chrome/browser/chromeos/login/account_screen.h" #include "base/string_util.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/login/account_creation_view.h" #include "chrome/browser/chromeos/login/screen_observer.h" #include "chrome/browser/profile_manager.h" @@ -130,6 +132,15 @@ void AccountScreen::NavigationStateChanged(const TabContents* source, // AccountScreen, WebPageDelegate implementation: void AccountScreen::OnPageLoaded() { StopTimeoutTimer(); + // Enable input methods (e.g. Chinese, Japanese) so that users could input + // their first and last names. + if (g_browser_process) { + const std::string locale = g_browser_process->GetApplicationLocale(); + input_method::EnableInputMethods( + locale, input_method::kKeyboardLayoutsOnly, ""); + // TODO(yusukes,suzhe): Change the 2nd argument to kAllInputMethods when + // crosbug.com/2670 is fixed. + } view()->ShowPageContent(); } @@ -148,6 +159,13 @@ void AccountScreen::OnUserCreated(const std::string& username, // AccountScreen, private: void AccountScreen::CloseScreen(ScreenObserver::ExitCodes code) { StopTimeoutTimer(); + // Disable input methods since they are not necessary to input username and + // password. + if (g_browser_process) { + const std::string locale = g_browser_process->GetApplicationLocale(); + input_method::EnableInputMethods( + locale, input_method::kKeyboardLayoutsOnly, ""); + } delegate()->GetObserver(this)->OnExit(code); } diff --git a/chrome/browser/chromeos/login/language_switch_menu.cc b/chrome/browser/chromeos/login/language_switch_menu.cc index fceddc5..ae64358 100644 --- a/chrome/browser/chromeos/login/language_switch_menu.cc +++ b/chrome/browser/chromeos/login/language_switch_menu.cc @@ -8,6 +8,8 @@ #include "app/resource_bundle.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/input_method/input_method_util.h" +#include "chrome/browser/chromeos/language_preferences.h" #include "chrome/browser/chromeos/login/screen_observer.h" #include "chrome/browser/pref_service.h" #include "chrome/common/pref_names.h" @@ -92,6 +94,11 @@ void LanguageSwitchMenu::SwitchLanguage(const std::string& locale) { // Switch the locale. ResourceBundle::ReloadSharedInstance(UTF8ToWide(locale)); + // Enable the keyboard layouts that are necessary for the new locale. + chromeos::input_method::EnableInputMethods( + locale, chromeos::input_method::kKeyboardLayoutsOnly, + kHardwareKeyboardLayout); + // The following line does not seem to affect locale anyhow. Maybe in future.. g_browser_process->SetApplicationLocale(locale); } diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index dd96148..95c9782 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc @@ -19,6 +19,7 @@ #include "chrome/browser/chromeos/cros/login_library.h" #include "chrome/browser/chromeos/cros/system_library.h" #include "chrome/browser/chromeos/customization_document.h" +#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/login/account_screen.h" #include "chrome/browser/chromeos/login/background_view.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" @@ -570,6 +571,18 @@ void ShowLoginWizard(const std::string& first_screen_name, // Tell the window manager that the user isn't logged in. chromeos::WmIpc::instance()->SetLoggedInProperty(false); + // 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()) { + const std::string locale = g_browser_process->GetApplicationLocale(); + const std::string initial_input_method_id = + g_browser_process->local_state()->GetString( + chromeos::kPreferredKeyboardLayout); + chromeos::input_method::EnableInputMethods( + locale, chromeos::input_method::kKeyboardLayoutsOnly, + initial_input_method_id); + } + gfx::Rect screen_bounds(CalculateScreenBounds(size)); // Check whether we need to execute OOBE process. diff --git a/chrome/browser/chromeos/status/language_menu_button.cc b/chrome/browser/chromeos/status/language_menu_button.cc index 0f14de0..3bc27e7 100644 --- a/chrome/browser/chromeos/status/language_menu_button.cc +++ b/chrome/browser/chromeos/status/language_menu_button.cc @@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/status/status_area_host.h" #include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -125,7 +126,8 @@ LanguageMenuButton::LanguageMenuButton(StatusAreaHost* host) // in this class. Therefore, GetItemCount() have to return 0 when // |model_| is NULL. ALLOW_THIS_IN_INITIALIZER_LIST(language_menu_(this)), - host_(host) { + host_(host), + logged_in_(false) { DCHECK(input_method_descriptors_.get() && !input_method_descriptors_->empty()); set_border(NULL); @@ -152,22 +154,31 @@ LanguageMenuButton::LanguageMenuButton(StatusAreaHost* host) // InputMethodChanged() will be called soon and the indicator will be updated. InputMethodLibrary* library = CrosLibrary::Get()->GetInputMethodLibrary(); PrefService* pref_service = GetPrefService(host_); - if (pref_service) { + if (pref_service && host_->IsBrowserMode()) { previous_input_method_pref_.Init( prefs::kLanguagePreviousInputMethod, pref_service, this); - const std::string& previous_input_method_id = + const std::string previous_input_method_id = previous_input_method_pref_.GetValue(); if (!previous_input_method_id.empty()) library->ChangeInputMethod(previous_input_method_id); current_input_method_pref_.Init( prefs::kLanguageCurrentInputMethod, pref_service, this); - const std::string& current_input_method_id = + const std::string current_input_method_id = current_input_method_pref_.GetValue(); if (!current_input_method_id.empty()) library->ChangeInputMethod(current_input_method_id); } library->AddObserver(this); + + if (host_->IsBrowserMode() || host_->IsScreenLockerMode()) { + logged_in_ = true; + } + if (!logged_in_) { + registrar_.Add(this, + NotificationType::LOGIN_USER_CHANGED, + NotificationService::AllSources()); + } } LanguageMenuButton::~LanguageMenuButton() { @@ -355,13 +366,13 @@ void LanguageMenuButton::ActivatedAt(int index) { } } // Then, activate the property clicked. - CrosLibrary::Get()->GetInputMethodLibrary()->SetImePropertyActivated(key, - true); + CrosLibrary::Get()->GetInputMethodLibrary()->SetImePropertyActivated( + key, true); } else { // Command button like "Switch to half punctuation mode" is clicked. // We can always use "Deactivate" for command buttons. - CrosLibrary::Get()->GetInputMethodLibrary()->SetImePropertyActivated(key, - false); + CrosLibrary::Get()->GetInputMethodLibrary()->SetImePropertyActivated( + key, false); } return; } @@ -396,10 +407,22 @@ void LanguageMenuButton::InputMethodChanged(InputMethodLibrary* obj) { obj->current_input_method(); UpdateIndicatorFromInputMethod(current_input_method); // Update Chrome prefs as well. - if (GetPrefService(host_)) { - // Sometimes (e.g. initial boot) |previous_input_method.id| is empty. - previous_input_method_pref_.SetValue(previous_input_method.id); - current_input_method_pref_.SetValue(current_input_method.id); + if (host_->IsBrowserMode()) { + if (GetPrefService(host_)) { // make sure we're not in unit tests. + // Sometimes (e.g. initial boot) |previous_input_method.id| is empty. + previous_input_method_pref_.SetValue(previous_input_method.id); + current_input_method_pref_.SetValue(current_input_method.id); + } + } else { + // We're in the login screen (i.e. not in the normal browser mode nor screen + // locker mode). If a user has already logged in, we should not update the + // local state since a profile for the user might be loaded before the + // buttun for the login screen is destroyed. + if (!logged_in_ && g_browser_process && g_browser_process->local_state()) { + g_browser_process->local_state()->SetString( + kPreferredKeyboardLayout, current_input_method.id); + g_browser_process->local_state()->SavePersistentPrefs(); + } } } @@ -432,7 +455,8 @@ void LanguageMenuButton::UpdateIndicator( scoped_ptr<InputMethodDescriptors> active_input_methods( CrosLibrary::Get()->GetInputMethodLibrary()->GetActiveInputMethods()); if (active_input_methods->size() == 1 && - input_method::IsKeyboardLayout(active_input_methods->at(0).id)) { + input_method::IsKeyboardLayout(active_input_methods->at(0).id) && + host_->IsBrowserMode()) { // As the disabled color is set to invisible, disabling makes the // button disappear. SetEnabled(false); @@ -613,4 +637,16 @@ std::wstring LanguageMenuButton::GetTextForMenu( return text; } +void LanguageMenuButton::RegisterPrefs(PrefService* local_state) { + local_state->RegisterStringPref(kPreferredKeyboardLayout, ""); +} + +void LanguageMenuButton::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::LOGIN_USER_CHANGED) { + logged_in_ = true; + } +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/status/language_menu_button.h b/chrome/browser/chromeos/status/language_menu_button.h index b0483ce..dcafac1 100644 --- a/chrome/browser/chromeos/status/language_menu_button.h +++ b/chrome/browser/chromeos/status/language_menu_button.h @@ -10,7 +10,9 @@ #include "chrome/browser/chromeos/status/status_area_button.h" #include "chrome/browser/pref_member.h" #include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" #include "views/controls/menu/menu_2.h" #include "views/controls/menu/view_menu_delegate.h" @@ -58,7 +60,7 @@ class LanguageMenuButton : public views::MenuButton, // NotificationObserver implementation. virtual void Observe(NotificationType type, const NotificationSource& source, - const NotificationDetails& details) {} + const NotificationDetails& details); // Converts an InputMethodDescriptor object into human readable string. // Returns a text for the indicator on top right corner of the Chrome window. @@ -70,6 +72,9 @@ class LanguageMenuButton : public views::MenuButton, static std::wstring GetTextForMenu( const InputMethodDescriptor& input_method, bool add_method_name); + // Registers input method preferences for the login screen. + static void RegisterPrefs(PrefService* local_state); + protected: // views::View implementation. virtual void LocaleChanged(); @@ -121,6 +126,8 @@ class LanguageMenuButton : public views::MenuButton, views::Menu2 language_menu_; StatusAreaHost* host_; + NotificationRegistrar registrar_; + bool logged_in_; DISALLOW_COPY_AND_ASSIGN(LanguageMenuButton); }; |