diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java b/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java index 47e6fe5fb5..5ab75c66dc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/DynamicLanguageContextWrapper.java @@ -2,8 +2,10 @@ package org.thoughtcrime.securesms.util.dynamiclanguage; import android.content.Context; import android.content.res.Configuration; +import android.os.Build; import androidx.annotation.NonNull; +import androidx.core.os.LocaleListCompat; import org.thoughtcrime.securesms.util.TextSecurePreferences; @@ -15,7 +17,14 @@ import java.util.Locale; public final class DynamicLanguageContextWrapper { private DynamicLanguageContextWrapper() {} + private static LocaleListCompat systemLocaleList = LocaleListCompat.getEmptyLocaleList(); + public static void prepareOverrideConfiguration(@NonNull Context context, @NonNull Configuration base) { + if (Build.VERSION.SDK_INT >= 24) { + systemLocaleList = LocaleListCompat.wrap(base.getLocales()); + } else { + systemLocaleList = LocaleListCompat.create(base.locale); + } Locale newLocale = getUsersSelectedLocale(context); Locale.setDefault(newLocale); @@ -25,7 +34,7 @@ public final class DynamicLanguageContextWrapper { @SuppressWarnings("deprecated") public static @NonNull Locale getUsersSelectedLocale(@NonNull Context context) { String language = TextSecurePreferences.getLanguage(context); - return LocaleParser.findBestMatchingLocaleForLanguage(language); + return LocaleParser.findBestMatchingLocaleForLanguage(language, systemLocaleList); } public static void updateContext(@NonNull Context base) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParser.java b/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParser.java index 357181ab49..f0724c6f77 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParser.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParser.java @@ -1,8 +1,5 @@ package org.thoughtcrime.securesms.util.dynamiclanguage; -import android.content.res.Resources; -import android.os.Build; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.os.LocaleListCompat; @@ -21,12 +18,13 @@ final class LocaleParser { * Given a language, gets the best choice from the apps list of supported languages and the * Systems set of languages. */ - static @NonNull Locale findBestMatchingLocaleForLanguage(@Nullable String language) { + static @NonNull Locale findBestMatchingLocaleForLanguage(@Nullable String language, @NonNull LocaleListCompat systemLocaleList) { final Locale locale = LanguageString.parseLocale(language); if (appSupportsTheExactLocale(locale)) { return locale; } else { - return findBestSystemLocale(); + final Locale firstMatch = systemLocaleList.getFirstMatch(BuildConfig.LANGUAGES); + return firstMatch != null ? firstMatch : Locale.ENGLISH; } } @@ -36,24 +34,4 @@ final class LocaleParser { } return Arrays.asList(BuildConfig.LANGUAGES).contains(locale.toString()); } - - /** - * Get the first preferred language the app supports. - */ - private static @NonNull Locale findBestSystemLocale() { - LocaleListCompat localeList; - if (Build.VERSION.SDK_INT < 24) { - localeList = LocaleListCompat.create(Resources.getSystem().getConfiguration().locale); - } else { - localeList = LocaleListCompat.getAdjustedDefault(); - } - - final Locale firstMatch = localeList.getFirstMatch(BuildConfig.LANGUAGES); - - if (firstMatch != null) { - return firstMatch; - } - - return Locale.ENGLISH; - } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParserTest.java b/app/src/test/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParserTest.java index bc29f61581..1062ca3ba6 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParserTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/util/dynamiclanguage/LocaleParserTest.java @@ -1,6 +1,10 @@ package org.thoughtcrime.securesms.util.dynamiclanguage; import android.app.Application; +import android.content.res.Resources; + +import androidx.core.os.ConfigurationCompat; +import androidx.core.os.LocaleListCompat; import org.junit.Ignore; import org.junit.Test; @@ -24,7 +28,7 @@ public final class LocaleParserTest { @Test public void findBestMatchingLocaleForLanguage_all_build_config_languages_can_be_resolved() { for (String lang : buildConfigLanguages()) { - Locale locale = LocaleParser.findBestMatchingLocaleForLanguage(lang); + Locale locale = LocaleParser.findBestMatchingLocaleForLanguage(lang, getSystemLocales()); assertEquals(lang, locale.toString()); } } @@ -33,14 +37,14 @@ public final class LocaleParserTest { @Config(qualifiers = "fr") public void findBestMatchingLocaleForLanguage_a_non_build_config_language_defaults_to_device_value_which_is_supported_directly() { String unsupportedLanguage = getUnsupportedLanguage(); - assertEquals(Locale.FRENCH, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage)); + assertEquals(Locale.FRENCH, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage, getSystemLocales())); } @Test @Config(qualifiers = "en-rCA") public void findBestMatchingLocaleForLanguage_a_non_build_config_language_defaults_to_device_value_which_is_not_supported_directly() { String unsupportedLanguage = getUnsupportedLanguage(); - assertEquals(Locale.CANADA, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage)); + assertEquals(Locale.CANADA, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage, getSystemLocales())); } private static String getUnsupportedLanguage() { @@ -52,4 +56,8 @@ public final class LocaleParserTest { private static List buildConfigLanguages() { return Arrays.asList(BuildConfig.LANGUAGES); } + + private static LocaleListCompat getSystemLocales() { + return ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()); + } }