зеркало из 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;
|
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
|
@Override
|
||||||
public String getAndApplyPersistedLocale(Context context) {
|
public String getAndApplyPersistedLocale(Context context) {
|
||||||
initialize(context);
|
initialize(context);
|
||||||
|
|
|
@ -9,7 +9,6 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
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.ClearOnShutdownPref;
|
||||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||||
import org.mozilla.gecko.prompts.PromptService;
|
import org.mozilla.gecko.prompts.PromptService;
|
||||||
import org.mozilla.gecko.SmsManager;
|
|
||||||
import org.mozilla.gecko.updater.UpdateService;
|
import org.mozilla.gecko.updater.UpdateService;
|
||||||
import org.mozilla.gecko.updater.UpdateServiceHelper;
|
import org.mozilla.gecko.updater.UpdateServiceHelper;
|
||||||
import org.mozilla.gecko.util.ActivityResultHandler;
|
import org.mozilla.gecko.util.ActivityResultHandler;
|
||||||
|
@ -1207,6 +1205,9 @@ public abstract class GeckoApp
|
||||||
// the UI.
|
// the UI.
|
||||||
// This is using a sledgehammer to crack a nut, but it'll do for
|
// This is using a sledgehammer to crack a nut, but it'll do for
|
||||||
// now.
|
// 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()) {
|
if (BrowserLocaleManager.getInstance().systemLocaleDidChange()) {
|
||||||
Log.i(LOGTAG, "System locale changed. Restarting.");
|
Log.i(LOGTAG, "System locale changed. Restarting.");
|
||||||
doRestart();
|
doRestart();
|
||||||
|
@ -1317,29 +1318,36 @@ public abstract class GeckoApp
|
||||||
final String profilePath = getProfile().getDir().getAbsolutePath();
|
final String profilePath = getProfile().getDir().getAbsolutePath();
|
||||||
final EventDispatcher dispatcher = EventDispatcher.getInstance();
|
final EventDispatcher dispatcher = EventDispatcher.getInstance();
|
||||||
|
|
||||||
// Both of these are Java-format locale strings: "en_US", not "en-US".
|
// This is the locale prior to fixing it up.
|
||||||
final String osLocale = Locale.getDefault().toString();
|
final Locale osLocale = Locale.getDefault();
|
||||||
String appLocale = localeManager.getAndApplyPersistedLocale(GeckoApp.this);
|
|
||||||
Log.d(LOGTAG, "OS locale is " + osLocale + ", app locale is " + appLocale);
|
|
||||||
|
|
||||||
if (appLocale == null) {
|
// Both of these are Java-format locale strings: "en_US", not "en-US".
|
||||||
appLocale = osLocale;
|
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,
|
mHealthRecorder = GeckoApp.this.createHealthRecorder(GeckoApp.this,
|
||||||
profilePath,
|
profilePath,
|
||||||
dispatcher,
|
dispatcher,
|
||||||
osLocale,
|
osLocaleString,
|
||||||
appLocale,
|
appLocaleString,
|
||||||
previousSession);
|
previousSession);
|
||||||
|
|
||||||
final String uiLocale = appLocale;
|
final String uiLocale = appLocaleString;
|
||||||
ThreadUtils.postToUiThread(new Runnable() {
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GeckoApp.this.onLocaleReady(uiLocale);
|
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.androidBridge.browserApp = this;
|
||||||
|
|
||||||
|
Services.obs.addObserver(this, "Locale:OS", false);
|
||||||
Services.obs.addObserver(this, "Locale:Changed", false);
|
Services.obs.addObserver(this, "Locale:Changed", false);
|
||||||
Services.obs.addObserver(this, "Tab:Load", false);
|
Services.obs.addObserver(this, "Tab:Load", false);
|
||||||
Services.obs.addObserver(this, "Tab:Selected", false);
|
Services.obs.addObserver(this, "Tab:Selected", false);
|
||||||
|
@ -1771,6 +1772,34 @@ var BrowserApp = {
|
||||||
WebappManager.autoUninstall(JSON.parse(aData));
|
WebappManager.autoUninstall(JSON.parse(aData));
|
||||||
break;
|
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":
|
case "Locale:Changed":
|
||||||
if (aData) {
|
if (aData) {
|
||||||
// The value provided to Locale:Changed should be a BCP47 language tag
|
// 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
|
// Blow away the string cache so that future lookups get the
|
||||||
// correct locale.
|
// correct locale.
|
||||||
Services.strings.flushBundles();
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
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() {
|
get defaultBrowserWidth() {
|
||||||
delete this.defaultBrowserWidth;
|
delete this.defaultBrowserWidth;
|
||||||
let width = Services.prefs.getIntPref("browser.viewport.desktopWidth");
|
let width = Services.prefs.getIntPref("browser.viewport.desktopWidth");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче