Bug 1847701 - Accept-language format should be language-region format like Dekstop and Chrome/Android. r=geckoview-reviewers,necko-reviewers,platform-i18n-reviewers,valentin

As spec (RFC 7231), accept-language can accept language tag (BCP 47).

Currently, Firefox Android uses `Locale.toLanguageTag` API. But it may
append variant and extensions etc.

But Chrome/Android and desktop browser use <language>-<region> format for
this header, so we should use same format for compatibility.

Differential Revision: https://phabricator.services.mozilla.com/D203121
This commit is contained in:
Makoto Kato 2024-03-11 02:46:19 +00:00
Родитель 1a9a659014
Коммит a3d5a112dd
3 изменённых файлов: 19 добавлений и 25 удалений

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

@ -40,4 +40,16 @@ class LocaleTest : BaseSessionTest() {
equalTo(listOf("en-GB", "en-US", "en-FR")),
)
}
@Test
fun acceptLangaugeFormat() {
// No way to override default language settings from unit test.
// So we only test this on current settings.
val intlAcceptLanauge = "intl.accept_languages"
val prefValue = (sessionRule.getPrefs(intlAcceptLanauge)[0] as String).split(",")
for (value in prefValue) {
assertThat("Accept-Lanauge format should be language or language-region", value.filter { it == '-' }.count(), lessThanOrEqualTo(1))
}
}
}

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

@ -46,7 +46,6 @@ import android.os.Looper;
import android.os.PowerManager;
import android.os.Vibrator;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Display;
@ -1527,20 +1526,6 @@ public class GeckoAppShell {
}
}
private static String getLanguageTag(final Locale locale) {
final StringBuilder out = new StringBuilder(locale.getLanguage());
final String country = locale.getCountry();
final String variant = locale.getVariant();
if (!TextUtils.isEmpty(country)) {
out.append('-').append(country);
}
if (!TextUtils.isEmpty(variant)) {
out.append('-').append(variant);
}
// e.g. "en", "en-US", or "en-US-POSIX".
return out.toString();
}
@WrapForJNI
public static String[] getDefaultLocales() {
// XXX We may have to convert some language codes such as "id" vs "in".

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

@ -1056,7 +1056,7 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
}
}
// OS prefs come second:
for (final String locale : getDefaultLocales()) {
for (final String locale : getSystemLocalesForAcceptLanguage()) {
final String localeLowerCase = locale.toLowerCase(Locale.ROOT);
if (!locales.containsKey(localeLowerCase)) {
locales.put(localeLowerCase, locale);
@ -1066,32 +1066,29 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
return TextUtils.join(",", locales.values());
}
private static String[] getDefaultLocales() {
private static String[] getSystemLocalesForAcceptLanguage() {
if (VERSION.SDK_INT >= 24) {
final LocaleList localeList = LocaleList.getDefault();
final String[] locales = new String[localeList.size()];
for (int i = 0; i < localeList.size(); i++) {
locales[i] = localeList.get(i).toLanguageTag();
// accept-language should be language or language-region format.
locales[i] = getLanguageTagForAcceptLanguage(localeList.get(i));
}
return locales;
}
final String[] locales = new String[1];
final Locale locale = Locale.getDefault();
locales[0] = locale.toLanguageTag();
locales[0] = getLanguageTagForAcceptLanguage(locale);
return locales;
}
private static String getLanguageTag(final Locale locale) {
private static String getLanguageTagForAcceptLanguage(final Locale locale) {
final StringBuilder out = new StringBuilder(locale.getLanguage());
final String country = locale.getCountry();
final String variant = locale.getVariant();
if (!TextUtils.isEmpty(country)) {
out.append('-').append(country);
}
if (!TextUtils.isEmpty(variant)) {
out.append('-').append(variant);
}
// e.g. "en", "en-US", or "en-US-POSIX".
// e.g. "en", "en-US"
return out.toString();
}