Update system default language when switching.

This commit is contained in:
Michelle Tang
2025-04-02 15:39:54 -04:00
parent 45ea0c0c97
commit a073785407
3 changed files with 24 additions and 29 deletions

View File

@@ -2,8 +2,10 @@ package org.thoughtcrime.securesms.util.dynamiclanguage;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.os.LocaleListCompat;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -15,7 +17,14 @@ import java.util.Locale;
public final class DynamicLanguageContextWrapper { public final class DynamicLanguageContextWrapper {
private DynamicLanguageContextWrapper() {} private DynamicLanguageContextWrapper() {}
private static LocaleListCompat systemLocaleList = LocaleListCompat.getEmptyLocaleList();
public static void prepareOverrideConfiguration(@NonNull Context context, @NonNull Configuration base) { 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 newLocale = getUsersSelectedLocale(context);
Locale.setDefault(newLocale); Locale.setDefault(newLocale);
@@ -25,7 +34,7 @@ public final class DynamicLanguageContextWrapper {
@SuppressWarnings("deprecated") @SuppressWarnings("deprecated")
public static @NonNull Locale getUsersSelectedLocale(@NonNull Context context) { public static @NonNull Locale getUsersSelectedLocale(@NonNull Context context) {
String language = TextSecurePreferences.getLanguage(context); String language = TextSecurePreferences.getLanguage(context);
return LocaleParser.findBestMatchingLocaleForLanguage(language); return LocaleParser.findBestMatchingLocaleForLanguage(language, systemLocaleList);
} }
public static void updateContext(@NonNull Context base) { public static void updateContext(@NonNull Context base) {

View File

@@ -1,8 +1,5 @@
package org.thoughtcrime.securesms.util.dynamiclanguage; package org.thoughtcrime.securesms.util.dynamiclanguage;
import android.content.res.Resources;
import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.os.LocaleListCompat; 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 * Given a language, gets the best choice from the apps list of supported languages and the
* Systems set of languages. * 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); final Locale locale = LanguageString.parseLocale(language);
if (appSupportsTheExactLocale(locale)) { if (appSupportsTheExactLocale(locale)) {
return locale; return locale;
} else { } 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()); 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;
}
} }

View File

@@ -1,6 +1,10 @@
package org.thoughtcrime.securesms.util.dynamiclanguage; package org.thoughtcrime.securesms.util.dynamiclanguage;
import android.app.Application; 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.Ignore;
import org.junit.Test; import org.junit.Test;
@@ -24,7 +28,7 @@ public final class LocaleParserTest {
@Test @Test
public void findBestMatchingLocaleForLanguage_all_build_config_languages_can_be_resolved() { public void findBestMatchingLocaleForLanguage_all_build_config_languages_can_be_resolved() {
for (String lang : buildConfigLanguages()) { for (String lang : buildConfigLanguages()) {
Locale locale = LocaleParser.findBestMatchingLocaleForLanguage(lang); Locale locale = LocaleParser.findBestMatchingLocaleForLanguage(lang, getSystemLocales());
assertEquals(lang, locale.toString()); assertEquals(lang, locale.toString());
} }
} }
@@ -33,14 +37,14 @@ public final class LocaleParserTest {
@Config(qualifiers = "fr") @Config(qualifiers = "fr")
public void findBestMatchingLocaleForLanguage_a_non_build_config_language_defaults_to_device_value_which_is_supported_directly() { public void findBestMatchingLocaleForLanguage_a_non_build_config_language_defaults_to_device_value_which_is_supported_directly() {
String unsupportedLanguage = getUnsupportedLanguage(); String unsupportedLanguage = getUnsupportedLanguage();
assertEquals(Locale.FRENCH, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage)); assertEquals(Locale.FRENCH, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage, getSystemLocales()));
} }
@Test @Test
@Config(qualifiers = "en-rCA") @Config(qualifiers = "en-rCA")
public void findBestMatchingLocaleForLanguage_a_non_build_config_language_defaults_to_device_value_which_is_not_supported_directly() { public void findBestMatchingLocaleForLanguage_a_non_build_config_language_defaults_to_device_value_which_is_not_supported_directly() {
String unsupportedLanguage = getUnsupportedLanguage(); String unsupportedLanguage = getUnsupportedLanguage();
assertEquals(Locale.CANADA, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage)); assertEquals(Locale.CANADA, LocaleParser.findBestMatchingLocaleForLanguage(unsupportedLanguage, getSystemLocales()));
} }
private static String getUnsupportedLanguage() { private static String getUnsupportedLanguage() {
@@ -52,4 +56,8 @@ public final class LocaleParserTest {
private static List<String> buildConfigLanguages() { private static List<String> buildConfigLanguages() {
return Arrays.asList(BuildConfig.LANGUAGES); return Arrays.asList(BuildConfig.LANGUAGES);
} }
private static LocaleListCompat getSystemLocales() {
return ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration());
}
} }