Home | History | Annotate | Download | only in base
      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