diff --git a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java index 7fd43c22e49..aee360e22f6 100644 --- a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java +++ b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java @@ -37,6 +37,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.preference.Preference; import androidx.preference.PreferenceGroup; +import com.android.internal.app.LocalePicker; +import com.android.internal.app.LocalePicker.LocaleInfo; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; @@ -45,8 +47,11 @@ import com.android.settingslib.applications.AppUtils; import com.android.settingslib.widget.LayoutPreference; import com.android.settingslib.widget.RadioButtonPreference; +import com.google.common.collect.Iterables; + import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Locale; /** @@ -200,8 +205,8 @@ public class AppLocaleDetails extends AppInfoBase implements RadioButtonPreferen private TelephonyManager mTelephonyManager; private LocaleManager mLocaleManager; - private Collection mSuggestedLocales = new ArrayList<>();; - private Collection mSupportedLocales = new ArrayList<>();; + private Collection mSuggestedLocales = new ArrayList<>(); + private Collection mSupportedLocales = new ArrayList<>(); AppLocaleDetailsHelper(Context context, String packageName) { mContext = context; @@ -230,25 +235,41 @@ public class AppLocaleDetails extends AppInfoBase implements RadioButtonPreferen @VisibleForTesting void handleSuggestedLocales() { LocaleList currentSystemLocales = getCurrentSystemLocales(); - Locale simLocale = mTelephonyManager.getSimLocale(); Locale appLocale = getAppDefaultLocale(mContext, mPackageName); + String simCountry = mTelephonyManager.getSimCountryIso().toUpperCase(Locale.US); + String networkCountry = mTelephonyManager.getNetworkCountryIso().toUpperCase(Locale.US); // 1st locale in suggested languages group. if (appLocale != null) { mSuggestedLocales.add(appLocale); } // 2nd locale in suggested languages group. - if (simLocale != null && !compareLocale(simLocale, appLocale)) { - mSuggestedLocales.add(simLocale); + final List localeInfos = LocalePicker.getAllAssetLocales(mContext, false); + for (LocaleInfo localeInfo : localeInfos) { + Locale locale = localeInfo.getLocale(); + String localeCountry = locale.getCountry().toUpperCase(Locale.US); + if (!compareLocale(locale, appLocale) + && isCountrySuggestedLocale(localeCountry, simCountry, networkCountry)) { + mSuggestedLocales.add(locale); + } } // Other locales in suggested languages group. for (int i = 0; i < currentSystemLocales.size(); i++) { Locale locale = currentSystemLocales.get(i); - if (!compareLocale(locale, appLocale) && !compareLocale(locale, simLocale)) { + boolean isInSuggestedLocales = false; + for (int j = 0; j < mSuggestedLocales.size(); j++) { + Locale suggestedLocale = Iterables.get(mSuggestedLocales, j); + if (compareLocale(locale, suggestedLocale)) { + isInSuggestedLocales = true; + break; + } + } + if (!isInSuggestedLocales) { mSuggestedLocales.add(locale); } } } + @VisibleForTesting static boolean compareLocale(Locale source, Locale target) { if (source == null && target == null) { return true; @@ -259,6 +280,13 @@ public class AppLocaleDetails extends AppInfoBase implements RadioButtonPreferen } } + private static boolean isCountrySuggestedLocale(String localeCountry, + String simCountry, + String networkCountry) { + return ((!simCountry.isEmpty() && simCountry.equals(localeCountry)) + || (!networkCountry.isEmpty() && networkCountry.equals(localeCountry))); + } + @VisibleForTesting void handleSupportedLocales() { //TODO Waiting for PackageManager api diff --git a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java index e185354e5ed..1042a6a20a7 100644 --- a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java +++ b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java @@ -53,7 +53,6 @@ public class AppLocaleDetailsTest { private Context mContext; private LocaleList mSystemLocales; - private Locale mSimLocale; private LocaleList mAppLocale; private String[] mAssetLocales; @@ -69,7 +68,8 @@ public class AppLocaleDetailsTest { when(mContext.getSystemService(LocaleManager.class)).thenReturn(mLocaleManager); setupInitialLocales("en", - "uk", + "tw", + "jp", "en, uk, jp, ne", new String[]{"en", "ne", "ms", "pa"}); } @@ -88,6 +88,8 @@ public class AppLocaleDetailsTest { @Test @UiThreadTest public void handleAllLocalesData_1stLocaleOfSuggestedLocaleListIsAppLocale() { + Locale simCountryLocale = new Locale("zh", "TW"); + Locale networkCountryLocale = new Locale("ja", "JP"); DummyAppLocaleDetailsHelper helper = new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); @@ -95,25 +97,17 @@ public class AppLocaleDetailsTest { Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); assertTrue(locale.equals(mAppLocale.get(0))); + assertTrue(helper.getSuggestedLocales().contains(simCountryLocale)); + assertTrue(helper.getSuggestedLocales().contains(networkCountryLocale)); } @Test @UiThreadTest - public void handleAllLocalesData_2ndLocaleOfSuggestedLocaleListIsSimLocale() { - DummyAppLocaleDetailsHelper helper = - new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); - - helper.handleAllLocalesData(); - - Locale locale = Iterables.get(helper.getSuggestedLocales(), 1); - assertTrue(locale.equals(mSimLocale)); - } - - @Test - @UiThreadTest - public void handleAllLocalesData_withoutAppLocale_1stLocaleOfSuggestedLocaleListIsSimLocal() { + public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsSimCountryLocale() { + Locale simCountryLocale = new Locale("zh", "TW"); setupInitialLocales("", - "uk", + "tw", + "", "en, uk, jp, ne", new String[]{"en", "ne", "ms", "pa"}); DummyAppLocaleDetailsHelper helper = @@ -122,13 +116,34 @@ public class AppLocaleDetailsTest { helper.handleAllLocalesData(); Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); - assertTrue(locale.equals(mSimLocale)); + assertTrue(locale.equals(simCountryLocale)); + assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0))); } @Test @UiThreadTest - public void handleAllLocalesData_noAppAndSimLocale_1stLocaleIsFirstOneInSystemLocales() { + public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsNetworkCountryLocale() { + Locale networkCountryLocale = new Locale("en", "GB"); setupInitialLocales("", + "", + "gb", + "en, uk, jp, ne", + new String[]{"en", "ne", "ms", "pa"}); + DummyAppLocaleDetailsHelper helper = + new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME); + + helper.handleAllLocalesData(); + + Locale locale = Iterables.get(helper.getSuggestedLocales(), 0); + assertTrue(locale.equals(networkCountryLocale)); + assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0))); + } + + @Test + @UiThreadTest + public void handleAllLocalesData_noAppAndSimNetworkLocale_1stLocaleIsFirstOneInSystemLocales() { + setupInitialLocales("", + "", "", "en, uk, jp, ne", new String[]{"en", "ne", "ms", "pa"}); @@ -175,25 +190,34 @@ public class AppLocaleDetailsTest { /** * Sets the initial Locale data * - * @param appLocale Application locale, it shall be a language tag. - * example: "en" - * @param simLocale SIM carrier locale, it shall be a language tag. - * example: "en" - * @param systemLocales System locales, a locale list by a multiple language tags with comma. - * example: "en, uk, jp" - * @param assetLocales Asset locales, a locale list by a multiple language tags with String - * array. - * example: new String[] {"en", "ne", "ms", "pa"} + * @param appLocale Application locale, it shall be a language tag. + * example: "en" + * + * @param simCountry The ISO-3166-1 alpha-2 country code equivalent for the SIM + * provider's country code. + * example: "us" + * + * @param networkCountry The ISO-3166-1 alpha-2 country code equivalent of the MCC + * (Mobile Country Code) of the current registered operato + * or the cell nearby. + * example: "us" + * + * @param systemLocales System locales, a locale list by a multiple language tags with comma. + * example: "en, uk, jp" + * @param assetLocales Asset locales, a locale list by a multiple language tags with String + * array. + * example: new String[] {"en", "ne", "ms", "pa"} */ private void setupInitialLocales(String appLocale, - String simLocale, + String simCountry, + String networkCountry, String systemLocales, String[] assetLocales) { mAppLocale = LocaleList.forLanguageTags(appLocale); - mSimLocale = Locale.forLanguageTag(simLocale); mSystemLocales = LocaleList.forLanguageTags(systemLocales); mAssetLocales = assetLocales; - when(mTelephonyManager.getSimLocale()).thenReturn(simLocale.isEmpty() ? null : mSimLocale); + when(mTelephonyManager.getSimCountryIso()).thenReturn(simCountry); + when(mTelephonyManager.getNetworkCountryIso()).thenReturn(networkCountry); when(mLocaleManager.getApplicationLocales(anyString())).thenReturn(mAppLocale); }