зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1045053 - Part 1: set intl.accept_languages from Android OS/app locale. r=bnicholson
This commit is contained in:
Родитель
226fc0d222
Коммит
1018f86fc9
|
@ -248,6 +248,37 @@ public class BrowserLocaleManager implements LocaleManager {
|
|||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gecko needs to know the OS locale to compute a useful Accept-Language
|
||||
* header. If it changed since last time, send a message to Gecko and
|
||||
* persist the new value. If unchanged, returns immediately.
|
||||
*
|
||||
* @param prefs the SharedPreferences instance to use. Cannot be null.
|
||||
* @param osLocale the new locale instance. Safe if null.
|
||||
*/
|
||||
public static void storeAndNotifyOSLocale(final SharedPreferences prefs,
|
||||
final Locale osLocale) {
|
||||
if (osLocale == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String lastOSLocale = prefs.getString("osLocale", null);
|
||||
final String osLocaleString = osLocale.toString();
|
||||
|
||||
if (osLocaleString.equals(lastOSLocale)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the Java-native form.
|
||||
prefs.edit().putString("osLocale", osLocaleString).apply();
|
||||
|
||||
// The value we send to Gecko should be a language tag, not
|
||||
// a Java locale string.
|
||||
final String osLanguageTag = BrowserLocaleManager.getLanguageTag(osLocale);
|
||||
final GeckoEvent localeOSEvent = GeckoEvent.createBroadcastEvent("Locale:OS", osLanguageTag);
|
||||
GeckoAppShell.sendEventToGecko(localeOSEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAndApplyPersistedLocale(Context context) {
|
||||
initialize(context);
|
||||
|
|
|
@ -9,7 +9,6 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -45,7 +44,6 @@ import org.mozilla.gecko.mozglue.GeckoLoader;
|
|||
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
import org.mozilla.gecko.prompts.PromptService;
|
||||
import org.mozilla.gecko.SmsManager;
|
||||
import org.mozilla.gecko.updater.UpdateService;
|
||||
import org.mozilla.gecko.updater.UpdateServiceHelper;
|
||||
import org.mozilla.gecko.util.ActivityResultHandler;
|
||||
|
@ -1207,6 +1205,9 @@ public abstract class GeckoApp
|
|||
// the UI.
|
||||
// This is using a sledgehammer to crack a nut, but it'll do for
|
||||
// now.
|
||||
// Our OS locale pref will be detected as invalid after the
|
||||
// restart, and will be propagated to Gecko accordingly, so there's
|
||||
// no need to touch that here.
|
||||
if (BrowserLocaleManager.getInstance().systemLocaleDidChange()) {
|
||||
Log.i(LOGTAG, "System locale changed. Restarting.");
|
||||
doRestart();
|
||||
|
@ -1317,29 +1318,36 @@ public abstract class GeckoApp
|
|||
final String profilePath = getProfile().getDir().getAbsolutePath();
|
||||
final EventDispatcher dispatcher = EventDispatcher.getInstance();
|
||||
|
||||
// Both of these are Java-format locale strings: "en_US", not "en-US".
|
||||
final String osLocale = Locale.getDefault().toString();
|
||||
String appLocale = localeManager.getAndApplyPersistedLocale(GeckoApp.this);
|
||||
Log.d(LOGTAG, "OS locale is " + osLocale + ", app locale is " + appLocale);
|
||||
// This is the locale prior to fixing it up.
|
||||
final Locale osLocale = Locale.getDefault();
|
||||
|
||||
if (appLocale == null) {
|
||||
appLocale = osLocale;
|
||||
// Both of these are Java-format locale strings: "en_US", not "en-US".
|
||||
final String osLocaleString = osLocale.toString();
|
||||
String appLocaleString = localeManager.getAndApplyPersistedLocale(GeckoApp.this);
|
||||
Log.d(LOGTAG, "OS locale is " + osLocaleString + ", app locale is " + appLocaleString);
|
||||
|
||||
if (appLocaleString == null) {
|
||||
appLocaleString = osLocaleString;
|
||||
}
|
||||
|
||||
mHealthRecorder = GeckoApp.this.createHealthRecorder(GeckoApp.this,
|
||||
profilePath,
|
||||
dispatcher,
|
||||
osLocale,
|
||||
appLocale,
|
||||
osLocaleString,
|
||||
appLocaleString,
|
||||
previousSession);
|
||||
|
||||
final String uiLocale = appLocale;
|
||||
final String uiLocale = appLocaleString;
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GeckoApp.this.onLocaleReady(uiLocale);
|
||||
}
|
||||
});
|
||||
|
||||
// We use per-profile prefs here, because we're tracking against
|
||||
// a Gecko pref. The same applies to the locale switcher!
|
||||
BrowserLocaleManager.storeAndNotifyOSLocale(GeckoSharedPrefs.forProfile(GeckoApp.this), osLocale);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -342,6 +342,7 @@ var BrowserApp = {
|
|||
|
||||
Services.androidBridge.browserApp = this;
|
||||
|
||||
Services.obs.addObserver(this, "Locale:OS", false);
|
||||
Services.obs.addObserver(this, "Locale:Changed", false);
|
||||
Services.obs.addObserver(this, "Tab:Load", false);
|
||||
Services.obs.addObserver(this, "Tab:Selected", false);
|
||||
|
@ -1771,6 +1772,34 @@ var BrowserApp = {
|
|||
WebappManager.autoUninstall(JSON.parse(aData));
|
||||
break;
|
||||
|
||||
case "Locale:OS":
|
||||
// We know the system locale. We use this for generating Accept-Language headers.
|
||||
console.log("Locale:OS: " + aData);
|
||||
let currentOSLocale;
|
||||
try {
|
||||
currentOSLocale = Services.prefs.getCharPref("intl.locale.os");
|
||||
} catch (e) {
|
||||
}
|
||||
if (currentOSLocale == aData) {
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("New OS locale.");
|
||||
|
||||
// Ensure that this choice is immediately persisted, because
|
||||
// Gecko won't be told again if it forgets.
|
||||
Services.prefs.setCharPref("intl.locale.os", aData);
|
||||
Services.prefs.savePrefFile(null);
|
||||
|
||||
let appLocale;
|
||||
try {
|
||||
appLocale = Services.prefs.getCharPref("general.useragent.locale");
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
this.computeAcceptLanguages(aData, appLocale);
|
||||
break;
|
||||
|
||||
case "Locale:Changed":
|
||||
if (aData) {
|
||||
// The value provided to Locale:Changed should be a BCP47 language tag
|
||||
|
@ -1792,6 +1821,16 @@ var BrowserApp = {
|
|||
// Blow away the string cache so that future lookups get the
|
||||
// correct locale.
|
||||
Services.strings.flushBundles();
|
||||
|
||||
// Make sure we use the right Accept-Language header.
|
||||
let osLocale;
|
||||
try {
|
||||
// This should never not be set at this point, but better safe than sorry.
|
||||
osLocale = Services.prefs.getCharPref("intl.locale.os");
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
this.computeAcceptLanguages(osLocale, aData);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1801,6 +1840,63 @@ var BrowserApp = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set intl.accept_languages accordingly.
|
||||
*
|
||||
* After Bug 881510 this will also accept a real Accept-Language choice as
|
||||
* input; all Accept-Language logic lives here.
|
||||
*
|
||||
* osLocale should never be null, but this method is safe regardless.
|
||||
* appLocale may explicitly be null.
|
||||
*/
|
||||
computeAcceptLanguages(osLocale, appLocale) {
|
||||
let defaultBranch = Services.prefs.getDefaultBranch(null);
|
||||
let defaultAccept = defaultBranch.getComplexValue("intl.accept_languages", Ci.nsIPrefLocalizedString).data;
|
||||
console.log("Default intl.accept_languages = " + defaultAccept);
|
||||
|
||||
// A guard for potential breakage. Bug 438031.
|
||||
// This should not be necessary, because we're reading from the default branch,
|
||||
// but better safe than sorry.
|
||||
if (defaultAccept && defaultAccept.startsWith("chrome://")) {
|
||||
defaultAccept = null;
|
||||
} else {
|
||||
// Ensure lowercase everywhere so we can compare.
|
||||
defaultAccept = defaultAccept.toLowerCase();
|
||||
}
|
||||
|
||||
if (appLocale) {
|
||||
appLocale = appLocale.toLowerCase();
|
||||
}
|
||||
|
||||
if (osLocale) {
|
||||
osLocale = osLocale.toLowerCase();
|
||||
}
|
||||
|
||||
// Eliminate values if they're present in the default.
|
||||
let chosen;
|
||||
if (defaultAccept) {
|
||||
// intl.accept_languages is a comma-separated list, with no q-value params. Those
|
||||
// are added when the header is generated.
|
||||
chosen = defaultAccept.split(",")
|
||||
.map(String.trim)
|
||||
.filter((x) => (x != appLocale && x != osLocale));
|
||||
} else {
|
||||
chosen = [];
|
||||
}
|
||||
|
||||
if (osLocale) {
|
||||
chosen.unshift(osLocale);
|
||||
}
|
||||
|
||||
if (appLocale && appLocale != osLocale) {
|
||||
chosen.unshift(appLocale);
|
||||
}
|
||||
|
||||
let result = chosen.join(",");
|
||||
console.log("Setting intl.accept_languages to " + result);
|
||||
Services.prefs.setCharPref("intl.accept_languages", result);
|
||||
},
|
||||
|
||||
get defaultBrowserWidth() {
|
||||
delete this.defaultBrowserWidth;
|
||||
let width = Services.prefs.getIntPref("browser.viewport.desktopWidth");
|
||||
|
|
Загрузка…
Ссылка в новой задаче