1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/base/locale_util.h" 6 7 #include <vector> 8 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/chromeos/input_method/input_method_util.h" 11 #include "chromeos/ime/input_method_manager.h" 12 #include "content/public/browser/browser_thread.h" 13 #include "ui/base/resource/resource_bundle.h" 14 #include "ui/gfx/platform_font_pango.h" 15 16 namespace chromeos { 17 18 namespace { 19 20 struct SwitchLanguageData { 21 SwitchLanguageData(const std::string& locale, 22 const bool enableLocaleKeyboardLayouts, 23 const bool login_layouts_only, 24 scoped_ptr<locale_util::SwitchLanguageCallback> callback) 25 : callback(callback.Pass()), 26 locale(locale), 27 enableLocaleKeyboardLayouts(enableLocaleKeyboardLayouts), 28 login_layouts_only(login_layouts_only), 29 success(false) {} 30 31 scoped_ptr<locale_util::SwitchLanguageCallback> callback; 32 33 const std::string locale; 34 const bool enableLocaleKeyboardLayouts; 35 const bool login_layouts_only; 36 std::string loaded_locale; 37 bool success; 38 }; 39 40 // Runs on SequencedWorkerPool thread under PostTaskAndReply(). 41 // So data is owned by "Reply" part of PostTaskAndReply() process. 42 void SwitchLanguageDoReloadLocale(SwitchLanguageData* data) { 43 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 44 45 data->loaded_locale = 46 ResourceBundle::GetSharedInstance().ReloadLocaleResources(data->locale); 47 48 data->success = !data->loaded_locale.empty(); 49 50 ResourceBundle::GetSharedInstance().ReloadFonts(); 51 } 52 53 // Callback after SwitchLanguageDoReloadLocale() back in UI thread. 54 void FinishSwitchLanguage(scoped_ptr<SwitchLanguageData> data) { 55 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 56 if (data->success) { 57 g_browser_process->SetApplicationLocale(data->loaded_locale); 58 59 if (data->enableLocaleKeyboardLayouts) { 60 // If we have switched the locale, enable the keyboard layouts that 61 // are necessary for the new locale. Change the current input method 62 // to the hardware keyboard layout since the input method currently in 63 // use may not be supported by the new locale (3rd parameter). 64 input_method::InputMethodManager* manager = 65 input_method::InputMethodManager::Get(); 66 manager->EnableLoginLayouts( 67 data->loaded_locale, 68 manager->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); 69 if (!data->login_layouts_only) { 70 // Enable all the other layouts 71 std::vector<std::string> candidates; 72 input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); 73 // Add input methods associated with the language. 74 util->GetInputMethodIdsFromLanguageCode( 75 data->loaded_locale, 76 input_method::kKeyboardLayoutsOnly, 77 &candidates); 78 for (std::vector<std::string>::const_iterator i = candidates.begin(); 79 i != candidates.end(); 80 ++i) 81 manager->EnableInputMethod(*i); 82 } 83 } 84 } 85 gfx::PlatformFontPango::ReloadDefaultFont(); 86 if (data->callback) 87 data->callback->Run(data->locale, data->loaded_locale, data->success); 88 } 89 90 } // namespace 91 92 namespace locale_util { 93 94 void SwitchLanguage(const std::string& locale, 95 const bool enableLocaleKeyboardLayouts, 96 const bool login_layouts_only, 97 scoped_ptr<SwitchLanguageCallback> callback) { 98 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 99 scoped_ptr<SwitchLanguageData> data( 100 new SwitchLanguageData(locale, 101 enableLocaleKeyboardLayouts, 102 login_layouts_only, 103 callback.Pass())); 104 base::Closure reloader( 105 base::Bind(&SwitchLanguageDoReloadLocale, base::Unretained(data.get()))); 106 content::BrowserThread::PostBlockingPoolTaskAndReply( 107 FROM_HERE, 108 reloader, 109 base::Bind(&FinishSwitchLanguage, base::Passed(data.Pass()))); 110 } 111 112 } // namespace locale_util 113 } // namespace chromeos 114