Bug 1346616 - Migrate callsites that are retrieving requested locale from pref, to use LocaleService::GetRequestedLocales. r=jfkthame,Pike

I'm adding a helper function mozILocaleService::GetRequestedLocale to simplify
most of the callsites that are looking for the first of the requested locales.

In most cases, I'm just matching the behavior of the code with reusing
LocaleService API instead of direct manipulation on the prefs.
That includes how I handle error case scenarios.

In case of sdk/l10n/locale.js I am reusing LocaleService heuristics over
the custom one from the file since the ones in LocaleService are just
more correct and unified accross the whole platform.

In case of FallbackEncoding I have to turn it into a nsIObserver to listen
to intl:requested-locales-changed.

MozReview-Commit-ID: 7rOr2CovLK

--HG--
extra : rebase_source : 2f166cf1746f389a035f7cf557edcadeacb10fa0
This commit is contained in:
Zibi Braniecki 2017-03-11 18:43:11 -08:00
Родитель 59c62bd61c
Коммит cce53c69bc
22 изменённых файлов: 114 добавлений и 342 удалений

Просмотреть файл

@ -11,58 +11,8 @@ const prefs = require("../preferences/service");
const { Cu, Cc, Ci } = require("chrome"); const { Cu, Cc, Ci } = require("chrome");
const { Services } = Cu.import("resource://gre/modules/Services.jsm"); const { Services } = Cu.import("resource://gre/modules/Services.jsm");
/**
* Gets the currently selected locale for display.
* Gets all usable locale that we can use sorted by priority of relevance
* @return Array of locales, begins with highest priority
*/
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale";
const PREF_ACCEPT_LANGUAGES = "intl.accept_languages";
function getPreferedLocales(caseSensitve) { function getPreferedLocales(caseSensitve) {
let locales = []; return Services.locale.getRequestedLocales();
function addLocale(locale) {
locale = locale.trim();
if (!caseSensitve)
locale = locale.toLowerCase();
if (locales.indexOf(locale) === -1)
locales.push(locale);
}
// Most important locale is OS one. But we use it, only if
// "intl.locale.matchOS" pref is set to `true`.
// Currently only used for multi-locales mobile builds.
// http://mxr.mozilla.org/mozilla-central/source/mobile/android/installer/Makefile.in#46
if (prefs.get(PREF_MATCH_OS_LOCALE, false)) {
let localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].
getService(Ci.nsILocaleService);
let osLocale = localeService.getLocaleComponentForUserAgent();
addLocale(osLocale);
}
// In some cases, mainly on Fennec and on Linux version,
// `general.useragent.locale` is a special 'localized' value, like:
// "chrome://global/locale/intl.properties"
let browserUiLocale = prefs.getLocalized(PREF_SELECTED_LOCALE, "") ||
prefs.get(PREF_SELECTED_LOCALE, "");
if (browserUiLocale)
addLocale(browserUiLocale);
// Third priority is the list of locales used for web content
let contentLocales = prefs.getLocalized(PREF_ACCEPT_LANGUAGES, "") ||
prefs.get(PREF_ACCEPT_LANGUAGES, "");
if (contentLocales) {
// This list is a string of locales seperated by commas.
// There is spaces after commas, so strip each item
for (let locale of contentLocales.split(","))
addLocale(locale.replace(/(^\s+)|(\s+$)/g, ""));
}
// Finally, we ensure that en-US is the final fallback if it wasn't added
addLocale("en-US");
return locales;
} }
exports.getPreferedLocales = getPreferedLocales; exports.getPreferedLocales = getPreferedLocales;

Просмотреть файл

@ -2,128 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { getPreferedLocales, findClosestLocale } = require("sdk/l10n/locale"); const { findClosestLocale } = require("sdk/l10n/locale");
const prefs = require("sdk/preferences/service");
const { Cc, Ci, Cu } = require("chrome");
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
const BundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale";
const PREF_ACCEPT_LANGUAGES = "intl.accept_languages";
function assertPrefered(assert, expected, msg) {
assert.equal(JSON.stringify(getPreferedLocales()), JSON.stringify(expected),
msg);
}
exports.testGetPreferedLocales = function(assert) {
prefs.set(PREF_MATCH_OS_LOCALE, false);
prefs.set(PREF_SELECTED_LOCALE, "");
prefs.set(PREF_ACCEPT_LANGUAGES, "");
assertPrefered(assert, ["en-us"],
"When all preferences are empty, we only have en-us");
prefs.set(PREF_SELECTED_LOCALE, "fr");
prefs.set(PREF_ACCEPT_LANGUAGES, "jp");
assertPrefered(assert, ["fr", "jp", "en-us"],
"We first have useragent locale, then web one and finally en-US");
prefs.set(PREF_SELECTED_LOCALE, "en-US");
prefs.set(PREF_ACCEPT_LANGUAGES, "en-US");
assertPrefered(assert, ["en-us"],
"We do not have duplicates");
prefs.set(PREF_SELECTED_LOCALE, "en-US");
prefs.set(PREF_ACCEPT_LANGUAGES, "fr");
assertPrefered(assert, ["en-us", "fr"],
"en-US can be first if specified by higher priority preference");
// Reset what we changed
prefs.reset(PREF_MATCH_OS_LOCALE);
prefs.reset(PREF_SELECTED_LOCALE);
prefs.reset(PREF_ACCEPT_LANGUAGES);
}
// In some cases, mainly on Fennec and on Linux version,
// `general.useragent.locale` is a special 'localized' value, like:
// "chrome://global/locale/intl.properties"
exports.testPreferedLocalizedLocale = function(assert) {
prefs.set(PREF_MATCH_OS_LOCALE, false);
let bundleURL = "chrome://global/locale/intl.properties";
prefs.setLocalized(PREF_SELECTED_LOCALE, bundleURL);
let contentLocale = "ja";
prefs.set(PREF_ACCEPT_LANGUAGES, contentLocale);
// Read manually the expected locale value from the property file
let expectedLocale = BundleService.createBundle(bundleURL).
GetStringFromName(PREF_SELECTED_LOCALE).
toLowerCase();
// First add the useragent locale
let expectedLocaleList = [expectedLocale];
// Then the content locale
if (expectedLocaleList.indexOf(contentLocale) == -1)
expectedLocaleList.push(contentLocale);
// Add default "en-us" fallback if the main language is not already en-us
if (expectedLocaleList.indexOf("en-us") == -1)
expectedLocaleList.push("en-us");
assertPrefered(assert, expectedLocaleList, "test localized pref value");
// Reset what we have changed
prefs.reset(PREF_MATCH_OS_LOCALE);
prefs.reset(PREF_SELECTED_LOCALE);
prefs.reset(PREF_ACCEPT_LANGUAGES);
}
// On Linux the PREF_ACCEPT_LANGUAGES pref can be a localized pref.
exports.testPreferedContentLocale = function(assert) {
prefs.set(PREF_MATCH_OS_LOCALE, false);
let noLocale = "",
bundleURL = "chrome://global/locale/intl.properties";
prefs.set(PREF_SELECTED_LOCALE, noLocale);
prefs.setLocalized(PREF_ACCEPT_LANGUAGES, bundleURL);
// Read the expected locale values from the property file
let expectedLocaleList = BundleService.createBundle(bundleURL).
GetStringFromName(PREF_ACCEPT_LANGUAGES).
split(",").
map(locale => locale.trim().toLowerCase());
// Add default "en-us" fallback if the main language is not already en-us
if (expectedLocaleList.indexOf("en-us") == -1)
expectedLocaleList.push("en-us");
assertPrefered(assert, expectedLocaleList, "test localized content locale pref value");
// Reset what we have changed
prefs.reset(PREF_MATCH_OS_LOCALE);
prefs.reset(PREF_SELECTED_LOCALE);
prefs.reset(PREF_ACCEPT_LANGUAGES);
}
exports.testPreferedOsLocale = function(assert) {
prefs.set(PREF_MATCH_OS_LOCALE, true);
prefs.set(PREF_SELECTED_LOCALE, "");
prefs.set(PREF_ACCEPT_LANGUAGES, "");
let expectedLocale = Services.locale.getAppLocaleAsLangTag().toLowerCase();
let expectedLocaleList = [expectedLocale];
// Add default "en-us" fallback if the main language is not already en-us
if (expectedLocale != "en-us")
expectedLocaleList.push("en-us");
assertPrefered(assert, expectedLocaleList, "Ensure that we select OS locale when related preference is set");
// Reset what we have changed
prefs.reset(PREF_MATCH_OS_LOCALE);
prefs.reset(PREF_SELECTED_LOCALE);
prefs.reset(PREF_ACCEPT_LANGUAGES);
}
exports.testFindClosestLocale = function(assert) { exports.testFindClosestLocale = function(assert) {
// Second param of findClosestLocale (aMatchLocales) have to be in lowercase // Second param of findClosestLocale (aMatchLocales) have to be in lowercase

Просмотреть файл

@ -19,11 +19,14 @@
#include "nsCOMArray.h" #include "nsCOMArray.h"
#include "nsDirectoryServiceUtils.h" #include "nsDirectoryServiceUtils.h"
#include "mozilla/ModuleUtils.h" #include "mozilla/ModuleUtils.h"
#include "mozilla/intl/LocaleService.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsString.h" #include "nsString.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
#include "nsIPrefLocalizedString.h" #include "nsIPrefLocalizedString.h"
using mozilla::intl::LocaleService;
namespace mozilla { namespace mozilla {
namespace browser { namespace browser {
@ -125,31 +128,18 @@ AppendDistroSearchDirs(nsIProperties* aDirSvc, nsCOMArray<nsIFile> &array)
} }
// we didn't have a defaultLocale, use the user agent locale // we didn't have a defaultLocale, use the user agent locale
nsCString locale; nsAutoCString locale;
nsCOMPtr<nsIPrefLocalizedString> prefString; LocaleService::GetInstance()->GetAppLocaleAsLangTag(locale);
rv = prefs->GetComplexValue("general.useragent.locale",
NS_GET_IID(nsIPrefLocalizedString),
getter_AddRefs(prefString));
if (NS_SUCCEEDED(rv)) {
nsAutoString wLocale;
prefString->GetData(getter_Copies(wLocale));
CopyUTF16toUTF8(wLocale, locale);
} else {
rv = prefs->GetCharPref("general.useragent.locale", getter_Copies(locale));
}
nsCOMPtr<nsIFile> curLocalePlugins;
rv = localePlugins->Clone(getter_AddRefs(curLocalePlugins));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIFile> curLocalePlugins; curLocalePlugins->AppendNative(locale);
rv = localePlugins->Clone(getter_AddRefs(curLocalePlugins)); rv = curLocalePlugins->Exists(&exists);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv) && exists) {
array.AppendObject(curLocalePlugins);
curLocalePlugins->AppendNative(locale); return; // all done
rv = curLocalePlugins->Exists(&exists);
if (NS_SUCCEEDED(rv) && exists) {
array.AppendObject(curLocalePlugins);
return; // all done
}
} }
} }
} }

Просмотреть файл

@ -57,7 +57,7 @@ DistributionCustomizer.prototype = {
}, },
get _locale() { get _locale() {
let locale = this._prefs.getCharPref("general.useragent.locale", "en-US"); const locale = Services.locale.getRequestedLocale() || "en-US";
this.__defineGetter__("_locale", () => locale); this.__defineGetter__("_locale", () => locale);
return this._locale; return this._locale;
}, },

Просмотреть файл

@ -133,7 +133,8 @@ function* runTests(options) {
}); });
}); });
yield SpecialPowers.pushPrefEnv({set: [["general.useragent.locale", "es-ES"]]}); let reqLoc = Services.locale.getRequestedLocales();
Services.locale.setRequestedLocales(["es-ES"]);
yield extension.startup(); yield extension.startup();
@ -141,7 +142,7 @@ function* runTests(options) {
yield extension.unload(); yield extension.unload();
yield SpecialPowers.popPrefEnv(); Services.locale.setRequestedLocales(reqLoc);
let node = document.getElementById(pageActionId); let node = document.getElementById(pageActionId);
is(node, null, "pageAction image removed from document"); is(node, null, "pageAction image removed from document");

Просмотреть файл

@ -21,22 +21,7 @@ function isSubObjectOf(expectedObj, actualObj, name) {
} }
function getLocale() { function getLocale() {
const localePref = "general.useragent.locale"; return Services.locale.getRequestedLocale() || undefined;
return getLocalizedPref(localePref, Services.prefs.getCharPref(localePref));
}
/**
* Wrapper for nsIPrefBranch::getComplexValue.
* @param aPrefName
* The name of the pref to get.
* @returns aDefault if the requested pref doesn't exist.
*/
function getLocalizedPref(aPrefName, aDefault) {
try {
return Services.prefs.getComplexValue(aPrefName, Ci.nsIPrefLocalizedString).data;
} catch (ex) {
return aDefault;
}
} }
function promiseEvent(aTarget, aEventName, aPreventDefault) { function promiseEvent(aTarget, aEventName, aPreventDefault) {

Просмотреть файл

@ -314,7 +314,7 @@ class ChromeActions {
} }
getLocale() { getLocale() {
return getStringPref("general.useragent.locale", "en-US"); return Services.locale.getRequestedLocale() || "en-US";
} }
getStrings(data) { getStrings(data) {

Просмотреть файл

@ -49,12 +49,6 @@ XPCOMUtils.defineLazyGetter(this, "gUnicodeConverter", function() {
const DIRECTORY_LINKS_FILE = "directoryLinks.json"; const DIRECTORY_LINKS_FILE = "directoryLinks.json";
const DIRECTORY_LINKS_TYPE = "application/json"; const DIRECTORY_LINKS_TYPE = "application/json";
// The preference that tells whether to match the OS locale
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
// The preference that tells what locale the user selected
const PREF_SELECTED_LOCALE = "general.useragent.locale";
// The preference that tells where to obtain directory links // The preference that tells where to obtain directory links
const PREF_DIRECTORY_SOURCE = "browser.newtabpage.directory.source"; const PREF_DIRECTORY_SOURCE = "browser.newtabpage.directory.source";
@ -166,8 +160,6 @@ var DirectoryLinksProvider = {
return Object.freeze({ return Object.freeze({
enhanced: PREF_NEWTAB_ENHANCED, enhanced: PREF_NEWTAB_ENHANCED,
linksURL: PREF_DIRECTORY_SOURCE, linksURL: PREF_DIRECTORY_SOURCE,
matchOSLocale: PREF_MATCH_OS_LOCALE,
prefSelectedLocale: PREF_SELECTED_LOCALE,
}); });
}, },
@ -188,26 +180,7 @@ var DirectoryLinksProvider = {
* @return the selected locale or "en-US" if none is selected * @return the selected locale or "en-US" if none is selected
*/ */
get locale() { get locale() {
let matchOS = Services.prefs.getBoolPref(PREF_MATCH_OS_LOCALE, false); return Services.locale.getRequestedLocale() || "en-US";
if (matchOS) {
return Cc["@mozilla.org/intl/ospreferences;1"].
getService(Ci.mozIOSPreferences).systemLocale;
}
try {
let locale = Services.prefs.getComplexValue(PREF_SELECTED_LOCALE,
Ci.nsIPrefLocalizedString);
if (locale) {
return locale.data;
}
} catch (e) {}
try {
return Services.prefs.getCharPref(PREF_SELECTED_LOCALE);
} catch (e) {}
return "en-US";
}, },
/** /**
@ -236,14 +209,11 @@ var DirectoryLinksProvider = {
case this._observedPrefs.linksURL: case this._observedPrefs.linksURL:
delete this.__linksURL; delete this.__linksURL;
// fallthrough
// Force directory download on changes to fetch related prefs
case this._observedPrefs.matchOSLocale:
case this._observedPrefs.prefSelectedLocale:
this._fetchAndCacheLinksIfNecessary(true); this._fetchAndCacheLinksIfNecessary(true);
break; break;
} }
} else if (aTopic === "intl:requested-locales-changed") {
this._fetchAndCacheLinksIfNecessary(true);
} }
}, },
@ -690,6 +660,7 @@ var DirectoryLinksProvider = {
init: function DirectoryLinksProvider_init() { init: function DirectoryLinksProvider_init() {
this._setDefaultEnhanced(); this._setDefaultEnhanced();
this._addPrefsObserver(); this._addPrefsObserver();
Services.obs.addObserver(this, "intl:requested-locales-changed", false);
// setup directory file path and last download timestamp // setup directory file path and last download timestamp
this._directoryFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, DIRECTORY_LINKS_FILE); this._directoryFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, DIRECTORY_LINKS_FILE);
this._lastDownloadMS = 0; this._lastDownloadMS = 0;
@ -1213,6 +1184,7 @@ var DirectoryLinksProvider = {
delete this.__linksURL; delete this.__linksURL;
this._removePrefsObserver(); this._removePrefsObserver();
this._removeObservers(); this._removeObservers();
Services.obs.removeObserver(this, "intl:requested-locales-changed");
}, },
addObserver: function DirectoryLinksProvider_addObserver(aObserver) { addObserver: function DirectoryLinksProvider_addObserver(aObserver) {

Просмотреть файл

@ -34,7 +34,6 @@ const kURLData = {"directory": [{"url": "http://example.com", "title": "LocalSou
const kTestURL = "data:application/json," + JSON.stringify(kURLData); const kTestURL = "data:application/json," + JSON.stringify(kURLData);
// DirectoryLinksProvider preferences // DirectoryLinksProvider preferences
const kLocalePref = DirectoryLinksProvider._observedPrefs.prefSelectedLocale;
const kSourceUrlPref = DirectoryLinksProvider._observedPrefs.linksURL; const kSourceUrlPref = DirectoryLinksProvider._observedPrefs.linksURL;
const kPingUrlPref = "browser.newtabpage.directory.ping"; const kPingUrlPref = "browser.newtabpage.directory.ping";
const kNewtabEnhancedPref = "browser.newtabpage.enhanced"; const kNewtabEnhancedPref = "browser.newtabpage.enhanced";
@ -51,7 +50,8 @@ const kFailURL = kBaseUrl + kFailPath;
const kPingUrl = kBaseUrl + kPingPath; const kPingUrl = kBaseUrl + kPingPath;
// app/profile/firefox.js are not avaialble in xpcshell: hence, preset them // app/profile/firefox.js are not avaialble in xpcshell: hence, preset them
Services.prefs.setCharPref(kLocalePref, "en-US"); const origReqLocales = Services.locale.getRequestedLocales();
Services.locale.setRequestedLocales(["en-US"]);
Services.prefs.setCharPref(kSourceUrlPref, kTestURL); Services.prefs.setCharPref(kSourceUrlPref, kTestURL);
Services.prefs.setCharPref(kPingUrlPref, kPingUrl); Services.prefs.setCharPref(kPingUrlPref, kPingUrl);
Services.prefs.setBoolPref(kNewtabEnhancedPref, true); Services.prefs.setBoolPref(kNewtabEnhancedPref, true);
@ -201,7 +201,7 @@ function promiseSetupDirectoryLinksProvider(options = {}) {
return Task.spawn(function*() { return Task.spawn(function*() {
let linksURL = options.linksURL || kTestURL; let linksURL = options.linksURL || kTestURL;
yield DirectoryLinksProvider.init(); yield DirectoryLinksProvider.init();
yield promiseDirectoryDownloadOnPrefChange(kLocalePref, options.locale || "en-US"); Services.locale.setRequestedLocales([options.locale || "en-US"]);
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, linksURL); yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, linksURL);
do_check_eq(DirectoryLinksProvider._linksURL, linksURL); do_check_eq(DirectoryLinksProvider._linksURL, linksURL);
DirectoryLinksProvider._lastDownloadMS = options.lastDownloadMS || 0; DirectoryLinksProvider._lastDownloadMS = options.lastDownloadMS || 0;
@ -210,7 +210,7 @@ function promiseSetupDirectoryLinksProvider(options = {}) {
function promiseCleanDirectoryLinksProvider() { function promiseCleanDirectoryLinksProvider() {
return Task.spawn(function*() { return Task.spawn(function*() {
yield promiseDirectoryDownloadOnPrefChange(kLocalePref, "en-US"); Services.locale.setRequestedLocales(["en-US"]);
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kTestURL); yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kTestURL);
yield DirectoryLinksProvider._clearFrequencyCap(); yield DirectoryLinksProvider._clearFrequencyCap();
yield DirectoryLinksProvider._loadInadjacentSites(); yield DirectoryLinksProvider._loadInadjacentSites();
@ -233,7 +233,7 @@ function run_test() {
do_register_cleanup(function() { do_register_cleanup(function() {
server.stop(function() { }); server.stop(function() { });
DirectoryLinksProvider.reset(); DirectoryLinksProvider.reset();
Services.prefs.clearUserPref(kLocalePref); Services.locale.setRequestedLocales(origReqLocales);
Services.prefs.clearUserPref(kSourceUrlPref); Services.prefs.clearUserPref(kSourceUrlPref);
Services.prefs.clearUserPref(kPingUrlPref); Services.prefs.clearUserPref(kPingUrlPref);
Services.prefs.clearUserPref(kNewtabEnhancedPref); Services.prefs.clearUserPref(kNewtabEnhancedPref);

Просмотреть файл

@ -10,6 +10,7 @@
#include "nsUConvPropertySearch.h" #include "nsUConvPropertySearch.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "nsIObserverService.h"
#include "mozilla/intl/LocaleService.h" #include "mozilla/intl/LocaleService.h"
using mozilla::intl::LocaleService; using mozilla::intl::LocaleService;
@ -29,21 +30,17 @@ static constexpr nsUConvProp nonParticipatingDomains[] = {
#include "nonparticipatingdomains.properties.h" #include "nonparticipatingdomains.properties.h"
}; };
NS_IMPL_ISUPPORTS(FallbackEncoding, nsIObserver)
FallbackEncoding* FallbackEncoding::sInstance = nullptr; FallbackEncoding* FallbackEncoding::sInstance = nullptr;
bool FallbackEncoding::sGuessFallbackFromTopLevelDomain = true; bool FallbackEncoding::sGuessFallbackFromTopLevelDomain = true;
FallbackEncoding::FallbackEncoding() FallbackEncoding::FallbackEncoding()
{ {
MOZ_COUNT_CTOR(FallbackEncoding);
MOZ_ASSERT(!FallbackEncoding::sInstance, MOZ_ASSERT(!FallbackEncoding::sInstance,
"Singleton already exists."); "Singleton already exists.");
} }
FallbackEncoding::~FallbackEncoding()
{
MOZ_COUNT_DTOR(FallbackEncoding);
}
void void
FallbackEncoding::Get(nsACString& aFallback) FallbackEncoding::Get(nsACString& aFallback)
{ {
@ -118,6 +115,16 @@ FallbackEncoding::PrefChanged(const char*, void*)
FallbackEncoding::sInstance->Invalidate(); FallbackEncoding::sInstance->Invalidate();
} }
NS_IMETHODIMP
FallbackEncoding::Observe(nsISupports *aSubject, const char *aTopic,
const char16_t *aData)
{
MOZ_ASSERT(FallbackEncoding::sInstance,
"Observe callback called with null fallback cache.");
FallbackEncoding::sInstance->Invalidate();
return NS_OK;
}
void void
FallbackEncoding::Initialize() FallbackEncoding::Initialize()
{ {
@ -127,11 +134,13 @@ FallbackEncoding::Initialize()
Preferences::RegisterCallback(FallbackEncoding::PrefChanged, Preferences::RegisterCallback(FallbackEncoding::PrefChanged,
"intl.charset.fallback.override", "intl.charset.fallback.override",
nullptr); nullptr);
Preferences::RegisterCallback(FallbackEncoding::PrefChanged,
"general.useragent.locale",
nullptr);
Preferences::AddBoolVarCache(&sGuessFallbackFromTopLevelDomain, Preferences::AddBoolVarCache(&sGuessFallbackFromTopLevelDomain,
"intl.charset.fallback.tld"); "intl.charset.fallback.tld");
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->AddObserver(sInstance, "intl:requested-locales-changed", true);
}
} }
void void
@ -139,6 +148,10 @@ FallbackEncoding::Shutdown()
{ {
MOZ_ASSERT(FallbackEncoding::sInstance, MOZ_ASSERT(FallbackEncoding::sInstance,
"Releasing non-existent fallback cache."); "Releasing non-existent fallback cache.");
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(sInstance, "intl:requested-locales-changed");
}
delete FallbackEncoding::sInstance; delete FallbackEncoding::sInstance;
FallbackEncoding::sInstance = nullptr; FallbackEncoding::sInstance = nullptr;
} }

Просмотреть файл

@ -7,14 +7,17 @@
#ifndef mozilla_dom_FallbackEncoding_h_ #ifndef mozilla_dom_FallbackEncoding_h_
#define mozilla_dom_FallbackEncoding_h_ #define mozilla_dom_FallbackEncoding_h_
#include "nsIObserver.h"
#include "nsString.h" #include "nsString.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class FallbackEncoding class FallbackEncoding : public nsIObserver
{ {
public: public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
/** /**
* Whether FromTopLevelDomain() should be used. * Whether FromTopLevelDomain() should be used.
@ -68,7 +71,7 @@ private:
static FallbackEncoding* sInstance; static FallbackEncoding* sInstance;
FallbackEncoding(); FallbackEncoding();
~FallbackEncoding(); virtual ~FallbackEncoding() {};
/** /**
* Invalidates the cache. * Invalidates the cache.

Просмотреть файл

@ -747,6 +747,24 @@ LocaleService::GetRequestedLocales(uint32_t* aCount, char*** aOutArray)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
LocaleService::GetRequestedLocale(nsACString& aRetVal)
{
AutoTArray<nsCString, 16> requestedLocales;
bool res = GetRequestedLocales(requestedLocales);
if (!res) {
NS_ERROR("Couldn't retrieve selected locales from prefs!");
return NS_ERROR_FAILURE;
}
if (requestedLocales.Length() > 0) {
aRetVal = requestedLocales[0];
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
LocaleService::SetRequestedLocales(const char** aRequested, LocaleService::SetRequestedLocales(const char** aRequested,
uint32_t aRequestedCount) uint32_t aRequestedCount)

Просмотреть файл

@ -143,6 +143,11 @@ interface mozILocaleService : nsISupports
void getRequestedLocales([optional] out unsigned long aCount, void getRequestedLocales([optional] out unsigned long aCount,
[retval, array, size_is(aCount)] out string aLocales); [retval, array, size_is(aCount)] out string aLocales);
/**
* Returns the top-requested locale from the user, or an empty string if none is set.
*/
ACString getRequestedLocale();
/** /**
* Sets a list of locales that the user requested the app to be * Sets a list of locales that the user requested the app to be
* localized to. * localized to.

Просмотреть файл

@ -117,6 +117,24 @@ add_test(function test_getRequestedLocales_matchOS() {
run_next_test(); run_next_test();
}); });
add_test(function test_getRequestedLocale() {
Services.prefs.setBoolPref(PREF_MATCH_OS_LOCALE, false);
Services.prefs.setCharPref(PREF_SELECTED_LOCALE, "tlh");
let requestedLocale = localeService.getRequestedLocale();
do_check_true(requestedLocale === "tlh", "requestedLocale returns the right value");
Services.prefs.setCharPref(PREF_SELECTED_LOCALE, "");
requestedLocale = localeService.getRequestedLocale();
do_check_true(requestedLocale === "", "requestedLocale returns empty value value");
Services.prefs.clearUserPref(PREF_MATCH_OS_LOCALE);
Services.prefs.clearUserPref(PREF_SELECTED_LOCALE);
run_next_test();
});
add_test(function test_setRequestedLocales() { add_test(function test_setRequestedLocales() {
localeService.setRequestedLocales([]); localeService.setRequestedLocales([]);

Просмотреть файл

@ -1647,15 +1647,7 @@ var BrowserApp = {
}, },
getUALocalePref: function () { getUALocalePref: function () {
try { return Services.locale.getRequestedLocale() || undefined;
return Services.prefs.getComplexValue("general.useragent.locale", Ci.nsIPrefLocalizedString).data;
} catch (e) {
try {
return Services.prefs.getCharPref("general.useragent.locale");
} catch (ee) {
return undefined;
}
}
}, },
getOSLocalePref: function () { getOSLocalePref: function () {

Просмотреть файл

@ -113,14 +113,9 @@ DirectoryProvider.prototype = {
return; return;
let curLocale = ""; let curLocale = "";
try { let reqLocales = Services.locales.getRequestedLocales();
curLocale = Services.prefs.getComplexValue("general.useragent.locale", Ci.nsIPrefLocalizedString).data; if (reqLocales.length > 0) {
} catch (e) { curLocale = reqLocales[0];
// eslint-disable-next-line mozilla/use-default-preference-values
try {
curLocale = Services.prefs.getCharPref("general.useragent.locale");
} catch (ee) {
}
} }
if (curLocale) { if (curLocale) {

Просмотреть файл

@ -36,6 +36,7 @@
#include "mozilla/SizePrintfMacros.h" #include "mozilla/SizePrintfMacros.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "mozilla/intl/LocaleService.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -62,6 +63,7 @@ using mozilla::OriginAttributes;
using mozilla::Preferences; using mozilla::Preferences;
using mozilla::TimeStamp; using mozilla::TimeStamp;
using mozilla::Telemetry::Accumulate; using mozilla::Telemetry::Accumulate;
using mozilla::intl::LocaleService;
using safe_browsing::ClientDownloadRequest; using safe_browsing::ClientDownloadRequest;
using safe_browsing::ClientDownloadRequest_CertificateChain; using safe_browsing::ClientDownloadRequest_CertificateChain;
using safe_browsing::ClientDownloadRequest_Resource; using safe_browsing::ClientDownloadRequest_Resource;
@ -73,7 +75,6 @@ using safe_browsing::ClientDownloadRequest_SignatureInfo;
#define PREF_SB_DOWNLOADS_ENABLED "browser.safebrowsing.downloads.enabled" #define PREF_SB_DOWNLOADS_ENABLED "browser.safebrowsing.downloads.enabled"
#define PREF_SB_DOWNLOADS_REMOTE_ENABLED "browser.safebrowsing.downloads.remote.enabled" #define PREF_SB_DOWNLOADS_REMOTE_ENABLED "browser.safebrowsing.downloads.remote.enabled"
#define PREF_SB_DOWNLOADS_REMOTE_TIMEOUT "browser.safebrowsing.downloads.remote.timeout_ms" #define PREF_SB_DOWNLOADS_REMOTE_TIMEOUT "browser.safebrowsing.downloads.remote.timeout_ms"
#define PREF_GENERAL_LOCALE "general.useragent.locale"
#define PREF_DOWNLOAD_BLOCK_TABLE "urlclassifier.downloadBlockTable" #define PREF_DOWNLOAD_BLOCK_TABLE "urlclassifier.downloadBlockTable"
#define PREF_DOWNLOAD_ALLOW_TABLE "urlclassifier.downloadAllowTable" #define PREF_DOWNLOAD_ALLOW_TABLE "urlclassifier.downloadAllowTable"
@ -1319,8 +1320,8 @@ PendingLookup::SendRemoteQueryInternal()
mRequest.set_user_initiated(true); mRequest.set_user_initiated(true);
nsCString locale; nsCString locale;
NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_GENERAL_LOCALE, &locale), rv = LocaleService::GetInstance()->GetAppLocaleAsLangTag(locale);
NS_ERROR_NOT_AVAILABLE); NS_ENSURE_SUCCESS(rv, rv);
mRequest.set_locale(locale.get()); mRequest.set_locale(locale.get());
nsCString sha256Hash; nsCString sha256Hash;
rv = mQuery->GetSha256Hash(sha256Hash); rv = mQuery->GetSha256Hash(sha256Hash);

Просмотреть файл

@ -875,12 +875,7 @@ function getDir(aKey, aIFace) {
* exists in nsHttpHandler.cpp when building the UA string. * exists in nsHttpHandler.cpp when building the UA string.
*/ */
function getLocale() { function getLocale() {
let locale = getLocalizedPref(LOCALE_PREF); return Services.locale.getRequestedLocale();
if (locale)
return locale;
// Not localized.
return Services.prefs.getCharPref(LOCALE_PREF);
} }
/** /**

Просмотреть файл

@ -9,26 +9,13 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale";
this.Locale = { this.Locale = {
/** /**
* Gets the currently selected locale for display. * Gets the currently selected locale for display.
* @return the selected locale or "en-US" if none is selected * @return the selected locale or "en-US" if none is selected
*/ */
getLocale() { getLocale() {
if (Preferences.get(PREF_MATCH_OS_LOCALE, false)) { return Services.locale.getRequestedLocale() || "en-US";
const osPrefs =
Cc["@mozilla.org/intl/ospreferences;1"].getService(Ci.mozIOSPreferences);
return osPrefs.systemLocale;
}
try {
let locale = Preferences.get(PREF_SELECTED_LOCALE, null, Ci.nsIPrefLocalizedString);
if (locale)
return locale;
} catch (e) {}
return Preferences.get(PREF_SELECTED_LOCALE, "en-US");
}, },
/** /**

Просмотреть файл

@ -41,8 +41,6 @@ const PREF_EM_HOTFIX_LASTVERSION = "extensions.hotfix.lastVersion";
const PREF_EM_HOTFIX_URL = "extensions.hotfix.url"; const PREF_EM_HOTFIX_URL = "extensions.hotfix.url";
const PREF_EM_CERT_CHECKATTRIBUTES = "extensions.hotfix.cert.checkAttributes"; const PREF_EM_CERT_CHECKATTRIBUTES = "extensions.hotfix.cert.checkAttributes";
const PREF_EM_HOTFIX_CERTS = "extensions.hotfix.certs."; const PREF_EM_HOTFIX_CERTS = "extensions.hotfix.certs.";
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale";
const UNKNOWN_XPCOM_ABI = "unknownABI"; const UNKNOWN_XPCOM_ABI = "unknownABI";
const PREF_MIN_WEBEXT_PLATFORM_VERSION = "extensions.webExtensionsMinPlatformVersion"; const PREF_MIN_WEBEXT_PLATFORM_VERSION = "extensions.webExtensionsMinPlatformVersion";
@ -326,26 +324,7 @@ function promiseCallProvider(aProvider, aMethod, ...aArgs) {
* @return the selected locale or "en-US" if none is selected * @return the selected locale or "en-US" if none is selected
*/ */
function getLocale() { function getLocale() {
try { return Services.locale.getRequestedLocale() || "en-US";
if (Services.prefs.getBoolPref(PREF_MATCH_OS_LOCALE)) {
const osPrefs =
Cc["@mozilla.org/intl/ospreferences;1"].getService(Ci.mozIOSPreferences);
return osPrefs.systemLocale;
}
} catch (e) { }
try {
let locale = Services.prefs.getComplexValue(PREF_SELECTED_LOCALE,
Ci.nsIPrefLocalizedString);
if (locale)
return locale;
} catch (e) { }
try {
return Services.prefs.getCharPref(PREF_SELECTED_LOCALE);
} catch (e) { }
return "en-US";
} }
function webAPIForAddon(addon) { function webAPIForAddon(addon) {

Просмотреть файл

@ -48,7 +48,6 @@ const PREF_BLOCKLIST_PINGCOUNTVERSION = "extensions.blocklist.pingCountVersion";
const PREF_BLOCKLIST_SUPPRESSUI = "extensions.blocklist.suppressUI"; const PREF_BLOCKLIST_SUPPRESSUI = "extensions.blocklist.suppressUI";
const PREF_ONECRL_VIA_AMO = "security.onecrl.via.amo"; const PREF_ONECRL_VIA_AMO = "security.onecrl.via.amo";
const PREF_BLOCKLIST_UPDATE_ENABLED = "services.blocklist.update_enabled"; const PREF_BLOCKLIST_UPDATE_ENABLED = "services.blocklist.update_enabled";
const PREF_GENERAL_USERAGENT_LOCALE = "general.useragent.locale";
const PREF_APP_DISTRIBUTION = "distribution.id"; const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version"; const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled"; const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled";
@ -242,14 +241,7 @@ function matchesOSABI(blocklistElement) {
* exists in nsHttpHandler.cpp when building the UA string. * exists in nsHttpHandler.cpp when building the UA string.
*/ */
function getLocale() { function getLocale() {
try { return Services.locale.getRequestedLocales();
// Get the default branch
var defaultPrefs = gPref.getDefaultBranch(null);
return defaultPrefs.getComplexValue(PREF_GENERAL_USERAGENT_LOCALE,
Ci.nsIPrefLocalizedString).data;
} catch (e) {}
return gPref.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
} }
/* Get the distribution pref values, from defaults only */ /* Get the distribution pref values, from defaults only */

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/ScopeExit.h" #include "mozilla/ScopeExit.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/intl/LocaleService.h"
#include "nsAppRunner.h" #include "nsAppRunner.h"
#include "mozilla/XREAppData.h" #include "mozilla/XREAppData.h"
@ -288,6 +289,7 @@ using mozilla::Unused;
using mozilla::scache::StartupCache; using mozilla::scache::StartupCache;
using mozilla::dom::ContentParent; using mozilla::dom::ContentParent;
using mozilla::dom::ContentChild; using mozilla::dom::ContentChild;
using mozilla::intl::LocaleService;
// Save literal putenv string to environment variable. // Save literal putenv string to environment variable.
static void static void
@ -4371,13 +4373,8 @@ XREMain::XRE_mainRun()
#ifdef MOZ_CRASHREPORTER #ifdef MOZ_CRASHREPORTER
nsCString userAgentLocale; nsCString userAgentLocale;
// Try a localized string first. This pref is always a localized string in LocaleService::GetInstance()->GetAppLocaleAsLangTag(userAgentLocale);
// Fennec, and might be elsewhere, too. CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale);
if (NS_SUCCEEDED(Preferences::GetLocalizedCString("general.useragent.locale", &userAgentLocale))) {
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale);
} else if (NS_SUCCEEDED(Preferences::GetCString("general.useragent.locale", &userAgentLocale))) {
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale);
}
#endif #endif
appStartup->GetShuttingDown(&mShuttingDown); appStartup->GetShuttingDown(&mShuttingDown);