diff options
author | Peter Varga <pvarga@inf.u-szeged.hu> | 2016-05-24 17:08:09 +0200 |
---|---|---|
committer | Peter Varga <pvarga@inf.u-szeged.hu> | 2016-07-13 21:12:03 +0000 |
commit | 89319455c36d48fe46a8501edd3c174c1de291fb (patch) | |
tree | 8ba7c33284a0b973090eb5de322ef466a859fbcf /src/core/resource_bundle_qt.cpp | |
parent | 9bb9076c50048913075f11692f784ebb959d63cf (diff) |
Fix changing locale of ResourceBundle on Linux
The ResourceBundle is not re-initialized for new Renderer Processes
because it is initialized only once in Zygote Process. This means runtime
locale changes do not affect new Renderer Processes. Zygote Process is
supported on Linux only thus other platforms don't need this fix.
With this change the locale of the ResourceBundle is reloaded when
new Renderer Process is started. For accessing the pak file of the locale
in the sandboxed environment the file descriptor is passed via the Chromium's
GlobalDescriptor solution.
Task-number: QTBUG-53000
Change-Id: I57e84078db9d0795d16d930aa1b3e93a6e86ec39
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core/resource_bundle_qt.cpp')
-rw-r--r-- | src/core/resource_bundle_qt.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp index ba25cc543..115dc56dc 100644 --- a/src/core/resource_bundle_qt.cpp +++ b/src/core/resource_bundle_qt.cpp @@ -38,10 +38,20 @@ ****************************************************************************/ #include "base/command_line.h" +#include "base/metrics/histogram.h" #include "content/public/common/content_switches.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/data_pack.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_switches.h" + #include "web_engine_library_info.h" +#if defined(OS_LINUX) +#include "base/posix/global_descriptors.h" +#include "global_descriptors_qt.h" +#endif + namespace ui { void ResourceBundle::LoadCommonResources() @@ -60,4 +70,62 @@ gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) return GetEmptyImage(); } +bool ResourceBundle::LocaleDataPakExists(const std::string& locale) +{ +#if defined(OS_LINUX) + base::CommandLine *parsed_command_line = base::CommandLine::ForCurrentProcess(); + std::string process_type = parsed_command_line->GetSwitchValueASCII(switches::kProcessType); + if (process_type == switches::kRendererProcess) { + // The Renderer Process is sandboxed thus only one locale is available in it. + // The particular one is passed by the --lang command line option. + if (!parsed_command_line->HasSwitch(switches::kLang) || parsed_command_line->GetSwitchValueASCII(switches::kLang) != locale) + return false; + + auto global_descriptors = base::GlobalDescriptors::GetInstance(); + return global_descriptors->MaybeGet(kWebEngineLocale) != -1; + } +#endif + + return !GetLocaleFilePath(locale, true).empty(); +} + +std::string ResourceBundle::LoadLocaleResources(const std::string& pref_locale) +{ + DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; + + std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); + +#if defined(OS_LINUX) + int locale_fd = base::GlobalDescriptors::GetInstance()->MaybeGet(kWebEngineLocale); + if (locale_fd > -1) { + scoped_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P)); + data_pack->LoadFromFile(base::File(locale_fd)); + locale_resources_data_.reset(data_pack.release()); + return app_locale; + } +#endif + + base::FilePath locale_file_path = GetOverriddenPakPath(); + if (locale_file_path.empty()) + locale_file_path = GetLocaleFilePath(app_locale, true); + + if (locale_file_path.empty()) { + // It's possible that there is no locale.pak. + LOG(WARNING) << "locale_file_path.empty() for locale " << app_locale; + return std::string(); + } + + scoped_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P)); + if (!data_pack->LoadFromPath(locale_file_path)) { + UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError", + logging::GetLastSystemErrorCode(), 16000); + LOG(ERROR) << "failed to load locale.pak"; + NOTREACHED(); + return std::string(); + } + + locale_resources_data_.reset(data_pack.release()); + return app_locale; +} + } // namespace ui |