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 16namespace chromeos { 17 18namespace { 19 20struct SwitchLanguageData { 21 SwitchLanguageData(const std::string& locale, 22 const bool enable_locale_keyboard_layouts, 23 const bool login_layouts_only, 24 scoped_ptr<locale_util::SwitchLanguageCallback> callback) 25 : callback(callback.Pass()), 26 locale(locale), 27 enable_locale_keyboard_layouts(enable_locale_keyboard_layouts), 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 enable_locale_keyboard_layouts; 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. 42void 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. 54void 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->enable_locale_keyboard_layouts) { 60 input_method::InputMethodManager* manager = 61 input_method::InputMethodManager::Get(); 62 scoped_refptr<input_method::InputMethodManager::State> ime_state = 63 manager->GetActiveIMEState(); 64 if (data->login_layouts_only) { 65 // Enable the hardware keyboard layouts and locale-specific layouts 66 // suitable for use on the login screen. This will also switch to the 67 // first hardware keyboard layout since the input method currently in 68 // use may not be supported by the new locale. 69 ime_state->EnableLoginLayouts( 70 data->loaded_locale, 71 manager->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); 72 } else { 73 // Enable all hardware keyboard layouts. This will also switch to the 74 // first hardware keyboard layout. 75 ime_state->ReplaceEnabledInputMethods( 76 manager->GetInputMethodUtil()->GetHardwareInputMethodIds()); 77 78 // Enable all locale-specific layouts. 79 std::vector<std::string> input_methods; 80 manager->GetInputMethodUtil()->GetInputMethodIdsFromLanguageCode( 81 data->loaded_locale, 82 input_method::kKeyboardLayoutsOnly, 83 &input_methods); 84 for (std::vector<std::string>::const_iterator it = 85 input_methods.begin(); it != input_methods.end(); ++it) { 86 ime_state->EnableInputMethod(*it); 87 } 88 } 89 } 90 } 91 gfx::PlatformFontPango::ReloadDefaultFont(); 92 if (data->callback) 93 data->callback->Run(data->locale, data->loaded_locale, data->success); 94} 95 96} // namespace 97 98namespace locale_util { 99 100void SwitchLanguage(const std::string& locale, 101 const bool enable_locale_keyboard_layouts, 102 const bool login_layouts_only, 103 scoped_ptr<SwitchLanguageCallback> callback) { 104 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 105 scoped_ptr<SwitchLanguageData> data( 106 new SwitchLanguageData(locale, 107 enable_locale_keyboard_layouts, 108 login_layouts_only, 109 callback.Pass())); 110 base::Closure reloader( 111 base::Bind(&SwitchLanguageDoReloadLocale, base::Unretained(data.get()))); 112 content::BrowserThread::PostBlockingPoolTaskAndReply( 113 FROM_HERE, 114 reloader, 115 base::Bind(&FinishSwitchLanguage, base::Passed(data.Pass()))); 116} 117 118} // namespace locale_util 119} // namespace chromeos 120