Bug 1434805 - Use LocaleList on Android N+. r=jchen
Android N+ has new Locale mode that selects multiple locale for font selection.
We should support it to be better locale system selection.
MozReview-Commit-ID: HndldWO5yOd
--- a/intl/locale/android/OSPreferences_android.cpp
+++ b/intl/locale/android/OSPreferences_android.cpp
@@ -25,20 +25,24 @@ OSPreferences::ReadSystemLocales(nsTArra
{
if (!mozilla::jni::IsAvailable()) {
return false;
}
//XXX: Notice, this value may be empty on an early read. In that case
// we won't add anything to the return list so that it doesn't get
// cached in mSystemLocales.
- auto locale = mozilla::jni::IsFennec() ? java::BrowserLocaleManager::GetLocale() :
- java::GeckoAppShell::GetDefaultLocale();
- if (locale) {
- aLocaleList.AppendElement(locale->ToCString());
+ auto locales = mozilla::jni::IsFennec() ?
+ java::BrowserLocaleManager::GetLocales() :
+ java::GeckoAppShell::GetDefaultLocales();
+ if (locales) {
+ for (size_t i = 0; i < locales->Length(); i++) {
+ jni::String::LocalRef locale = locales->GetElement(i);
+ aLocaleList.AppendElement(locale->ToCString());
+ }
return true;
}
return false;
}
bool
OSPreferences::ReadRegionalPrefsLocales(nsTArray<nsCString>& aLocaleList)
{
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserLocaleManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserLocaleManager.java
@@ -1,16 +1,17 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
package org.mozilla.gecko;
import java.io.File;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -22,16 +23,17 @@ import org.mozilla.gecko.util.GeckoJarRe
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
+import android.os.LocaleList;
import android.util.Log;
/**
* This class manages persistence, application, and otherwise handling of
* user-specified locales.
*
* Of note:
*
@@ -441,25 +443,35 @@ public class BrowserLocaleManager implem
return FALLBACK_LOCALE_TAG;
}
@WrapForJNI(dispatchTo = "Gecko")
private static native void refreshLocales();
@WrapForJNI
- private static String getLocale() {
+ private static String[] getLocales() {
try {
+ ArrayList<String> locales = new ArrayList<String>();
LocaleManager localeManager = Locales.getLocaleManager();
Context context = GeckoAppShell.getApplicationContext();
if (!localeManager.isMirroringSystemLocale(context)) {
// User uses specific browser locale instead of system locale
- return Locales.getLanguageTag(localeManager.getCurrentLocale(context));
+ locales.add(Locales.getLanguageTag(localeManager.getCurrentLocale(context)));
+ return locales.toArray(new String[locales.size()]);
}
- // Since user selects system default for browser locale, we should return system locale
- Locale locale = localeManager.getDefaultSystemLocale();
- return Locales.getLanguageTag(locale);
+ // Since user selects system default for browser locale, we should return system locales too.
+ if (Build.VERSION.SDK_INT >= 24) {
+ LocaleList localeList = LocaleList.getDefault();
+ for (int i = 0; i < localeList.size(); i++) {
+ // Some locales such as "he" need conversion.
+ locales.add(Locales.getLanguageTag(localeList.get(i)));
+ }
+ } else {
+ locales.add(Locales.getLanguageTag(localeManager.getDefaultSystemLocale()));
+ }
+ return locales.toArray(new String[locales.size()]);
} catch (NullPointerException e) {
Log.i(LOG_TAG, "Couldn't get current locale.");
return null;
}
}
}
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
@@ -74,16 +74,17 @@ import android.location.LocationListener
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.LocaleList;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.Settings;
import android.support.annotation.NonNull;
@@ -1915,28 +1916,44 @@ public class GeckoAppShell
}
final String prop = am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
if (prop == null) {
return DEFAULT;
}
return Integer.parseInt(prop);
}
- @WrapForJNI
- public static String getDefaultLocale() {
- final Locale locale = Locale.getDefault();
- if (Build.VERSION.SDK_INT >= 21) {
- return locale.toLanguageTag();
- }
-
+ 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".
+ if (Build.VERSION.SDK_INT >= 24) {
+ final LocaleList localeList = LocaleList.getDefault();
+ String[] locales = new String[localeList.size()];
+ for (int i = 0; i < localeList.size(); i++) {
+ locales[i] = localeList.get(i).toLanguageTag();
+ }
+ return locales;
+ }
+ String[] locales = new String[1];
+ final Locale locale = Locale.getDefault();
+ if (Build.VERSION.SDK_INT >= 21) {
+ locales[0] = locale.toLanguageTag();
+ return locales;
+ }
+
+ locales[0] = getLanguageTag(locale);
+ return locales;
+ }
}