diff options
author | bartfab@chromium.org <bartfab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-21 09:49:09 +0000 |
---|---|---|
committer | bartfab@chromium.org <bartfab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-21 09:50:46 +0000 |
commit | ac0eea1fbe4eeee3219f4c1a25c80f48324c9db7 (patch) | |
tree | 7f1fae30d0a099ba1c4c410de382a4a6486f893b /ui/base | |
parent | c283e5c5888d8a9807ca387aa7186da67b4340cd (diff) | |
download | chromium_src-ac0eea1fbe4eeee3219f4c1a25c80f48324c9db7.zip chromium_src-ac0eea1fbe4eeee3219f4c1a25c80f48324c9db7.tar.gz chromium_src-ac0eea1fbe4eeee3219f4c1a25c80f48324c9db7.tar.bz2 |
Do not switch the ICU locale when interacting with public session pods
When the user is choosing a language for a public session, Chrome needs
to verify that the selected locale is actually available, which can be
done by calling GetApplicationLocale(). However, that method has side
effects, in that it not only resolves the locale but also sets the ICU
default locale. This causes the ICU default locale to change
inadvertently while the user is interacting with the language picker.
This CL introduces a variant of GetApplicationLocale() without side
effects and uses that for public session pods.
BUG=403553
TEST=Extended unit and browser tests
Review URL: https://codereview.chromium.org/486203002
Cr-Commit-Position: refs/heads/master@{#291033}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291033 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base')
-rw-r--r-- | ui/base/l10n/l10n_util.cc | 22 | ||||
-rw-r--r-- | ui/base/l10n/l10n_util.h | 8 | ||||
-rw-r--r-- | ui/base/l10n/l10n_util_unittest.cc | 80 |
3 files changed, 100 insertions, 10 deletions
diff --git a/ui/base/l10n/l10n_util.cc b/ui/base/l10n/l10n_util.cc index 54b2848..a74719b 100644 --- a/ui/base/l10n/l10n_util.cc +++ b/ui/base/l10n/l10n_util.cc @@ -401,7 +401,7 @@ bool CheckAndResolveLocale(const std::string& locale, #endif } -std::string GetApplicationLocale(const std::string& pref_locale) { +std::string GetApplicationLocaleInternal(const std::string& pref_locale) { #if defined(OS_MACOSX) // Use any override (Cocoa for the browser), otherwise use the preference @@ -415,12 +415,6 @@ std::string GetApplicationLocale(const std::string& pref_locale) { if (app_locale.empty()) app_locale = "en-US"; - // Windows/Linux call SetICUDefaultLocale after determining the actual locale - // with CheckAndResolveLocal to make ICU APIs work in that locale. - // Mac doesn't use a locale directory tree of resources (it uses Mac style - // resources), so mirror the Windows/Linux behavior of calling - // SetICUDefaultLocale. - base::i18n::SetICUDefaultLocale(app_locale); return app_locale; #else @@ -482,7 +476,6 @@ std::string GetApplicationLocale(const std::string& pref_locale) { std::vector<std::string>::const_iterator i = candidates.begin(); for (; i != candidates.end(); ++i) { if (CheckAndResolveLocale(*i, &resolved_locale)) { - base::i18n::SetICUDefaultLocale(resolved_locale); return resolved_locale; } } @@ -490,7 +483,6 @@ std::string GetApplicationLocale(const std::string& pref_locale) { // Fallback on en-US. const std::string fallback_locale("en-US"); if (IsLocaleAvailable(fallback_locale)) { - base::i18n::SetICUDefaultLocale(fallback_locale); return fallback_locale; } @@ -499,6 +491,18 @@ std::string GetApplicationLocale(const std::string& pref_locale) { #endif } +std::string GetApplicationLocale(const std::string& pref_locale, + bool set_icu_locale) { + const std::string locale = GetApplicationLocaleInternal(pref_locale); + if (set_icu_locale && !locale.empty()) + base::i18n::SetICUDefaultLocale(locale); + return locale; +} + +std::string GetApplicationLocale(const std::string& pref_locale) { + return GetApplicationLocale(pref_locale, true /* set_icu_locale */); +} + bool IsLocaleNameTranslated(const char* locale, const std::string& display_locale) { base::string16 display_name = diff --git a/ui/base/l10n/l10n_util.h b/ui/base/l10n/l10n_util.h index 507fb734..e2cb27d 100644 --- a/ui/base/l10n/l10n_util.h +++ b/ui/base/l10n/l10n_util.h @@ -40,7 +40,13 @@ UI_BASE_EXPORT bool CheckAndResolveLocale(const std::string& locale, // command line (--lang), second we try the value in the prefs file (passed in // as |pref_locale|), finally, we fall back on the system locale. We only return // a value if there's a corresponding resource DLL for the locale. Otherwise, -// we fall back to en-us. +// we fall back to en-us. |set_icu_locale| determines whether the resulting +// locale is set as the default ICU locale before returning it. +UI_BASE_EXPORT std::string GetApplicationLocale(const std::string& pref_locale, + bool set_icu_locale); + +// Convenience version of GetApplicationLocale() that sets the resulting locale +// as the default ICU locale before returning it. UI_BASE_EXPORT std::string GetApplicationLocale(const std::string& pref_locale); // Returns true if a display name for |locale| is available in the locale diff --git a/ui/base/l10n/l10n_util_unittest.cc b/ui/base/l10n/l10n_util_unittest.cc index 9e2ae4d3..972dd26 100644 --- a/ui/base/l10n/l10n_util_unittest.cc +++ b/ui/base/l10n/l10n_util_unittest.cc @@ -141,12 +141,15 @@ TEST_F(L10nUtilTest, GetAppLocale) { base::i18n::SetICUDefaultLocale("en-US"); env->SetVar("LANGUAGE", "xx:fr_CA"); EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); env->SetVar("LANGUAGE", "xx:yy:en_gb.utf-8@quot"); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); env->SetVar("LANGUAGE", "xx:zh-hk"); EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); // We emulate gettext's behavior here, which ignores LANG/LC_MESSAGES/LC_ALL // when LANGUAGE is specified. If no language specified in LANGUAGE is @@ -155,9 +158,11 @@ TEST_F(L10nUtilTest, GetAppLocale) { base::i18n::SetICUDefaultLocale("fr-FR"); env->SetVar("LANGUAGE", "xx:yy"); EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); env->SetVar("LANGUAGE", "/fr:zh_CN"); EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); // Test prioritization of the different environment variables. env->SetVar("LANGUAGE", "fr"); @@ -165,35 +170,46 @@ TEST_F(L10nUtilTest, GetAppLocale) { env->SetVar("LC_MESSAGES", "he"); env->SetVar("LANG", "nb"); EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); env->UnSetVar("LANGUAGE"); EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); env->UnSetVar("LC_ALL"); EXPECT_EQ("he", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); env->UnSetVar("LC_MESSAGES"); EXPECT_EQ("nb", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("nb", icu::Locale::getDefault().getLanguage()); env->UnSetVar("LANG"); SetDefaultLocaleForTest("ca", env.get()); EXPECT_EQ("ca", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("ca-ES", env.get()); EXPECT_EQ("ca", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("ca@valencia", env.get()); EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("ca_ES@valencia", env.get()); EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("ca_ES.UTF8@valencia", env.get()); EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); } SetDefaultLocaleForTest("en-US", env.get()); EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("xx", env.get()); EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); if (!kPlatformHasDefaultLocale) { // ChromeOS & embedded use only browser prefs in GetApplicationLocale(), @@ -201,88 +217,148 @@ TEST_F(L10nUtilTest, GetAppLocale) { // the default locale from the OS or environment. SetDefaultLocaleForTest("en-GB", env.get()); EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-US", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-GB")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-US", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-AU")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-US", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-NZ")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-US", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-CA")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-US", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-ZA")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); } else { // Most platforms have an OS-provided locale. This locale is preferred. SetDefaultLocaleForTest("en-GB", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("fr-CA", env.get()); EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("es-MX", env.get()); EXPECT_EQ("es-419", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("es-AR", env.get()); EXPECT_EQ("es-419", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("es-ES", env.get()); EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("es", env.get()); EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("zh-HK", env.get()); EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("zh-MO", env.get()); EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("zh-SG", env.get()); EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-CA", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-AU", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-NZ", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); SetDefaultLocaleForTest("en-ZA", env.get()); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); } + SetDefaultLocaleForTest("en-US", env.get()); + if (kSupportsLocalePreference) { // On windows, the user can override the locale in preferences. base::i18n::SetICUDefaultLocale("en-US"); EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr")); + EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr-CA")); + EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); base::i18n::SetICUDefaultLocale("en-US"); // Aliases iw, no, tl to he, nb, fil. EXPECT_EQ("he", l10n_util::GetApplicationLocale("iw")); + EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); EXPECT_EQ("nb", l10n_util::GetApplicationLocale("no")); + EXPECT_STREQ("nb", icu::Locale::getDefault().getLanguage()); EXPECT_EQ("fil", l10n_util::GetApplicationLocale("tl")); + EXPECT_STREQ("fil", icu::Locale::getDefault().getLanguage()); // es-419 and es-XX (where XX is not Spain) should be // mapped to es-419 (Latin American Spanish). EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-419")); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); EXPECT_EQ("es", l10n_util::GetApplicationLocale("es-ES")); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-AR")); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); base::i18n::SetICUDefaultLocale("es-AR"); EXPECT_EQ("es", l10n_util::GetApplicationLocale("es")); + EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); base::i18n::SetICUDefaultLocale("zh-HK"); EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale("zh-CN")); + EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); base::i18n::SetICUDefaultLocale("he"); EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); + + base::i18n::SetICUDefaultLocale("he"); + EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en", false)); + EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); + + base::i18n::SetICUDefaultLocale("de"); + EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("xx", false)); + EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); + + base::i18n::SetICUDefaultLocale("de"); + EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr", false)); + EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); + + base::i18n::SetICUDefaultLocale("de"); + EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en", false)); + EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); + + base::i18n::SetICUDefaultLocale("de"); + EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en-US", true)); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); + } else { + base::i18n::SetICUDefaultLocale("de"); + EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string(), false)); + EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); + + base::i18n::SetICUDefaultLocale("de"); + EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string(), true)); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); } #if defined(OS_WIN) @@ -290,13 +366,17 @@ TEST_F(L10nUtilTest, GetAppLocale) { if (base::win::GetVersion() < base::win::VERSION_VISTA) { base::i18n::SetICUDefaultLocale("am"); EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); base::i18n::SetICUDefaultLocale("en-GB"); EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("am")); + EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); } else { base::i18n::SetICUDefaultLocale("am"); EXPECT_EQ("am", l10n_util::GetApplicationLocale("")); + EXPECT_STREQ("am", icu::Locale::getDefault().getLanguage()); base::i18n::SetICUDefaultLocale("en-GB"); EXPECT_EQ("am", l10n_util::GetApplicationLocale("am")); + EXPECT_STREQ("am", icu::Locale::getDefault().getLanguage()); } #endif // defined(OS_WIN) |