Visibility changes to allow access by SetupWizard

Also adding a method that is called when the SIM info changes,
to update sugestions.
This is a must for SetupWizard, where the language selection can
be displayed before the SIM is fully initialized.
Might also use it to update suggested locals when SIM status changes
(SIM card replaced, or the user crosses border to a different country)

Bug: 25797548
Change-Id: I1a68b4e71046caa3b2810b37c74be5eeb00a255c
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
index 5ac786a..71c2c21 100644
--- a/core/java/com/android/internal/app/LocaleHelper.java
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -24,7 +24,7 @@
 import java.util.Locale;
 
 /**
- * This class implements some handy methods to proces with locales.
+ * This class implements some handy methods to process with locales.
  */
 public class LocaleHelper {
 
@@ -55,7 +55,7 @@
      *       source, breakIterator, UCharacter.TITLECASE_NO_LOWERCASE);
      * }}
      *
-     * <p>That also means creating BreakIteratos for each locale. Expensive...</p>
+     * <p>That also means creating a BreakIterator for each locale. Expensive...</p>
      *
      * @param str the string to sentence-case.
      * @param locale the locale used for the case conversion.
@@ -180,7 +180,7 @@
      *
      * <p>Gives priority to suggested locales (to sort them at the top).</p>
      */
-    static final class LocaleInfoComparator implements Comparator<LocaleStore.LocaleInfo> {
+    public static final class LocaleInfoComparator implements Comparator<LocaleStore.LocaleInfo> {
         private final Collator mCollator;
 
         /**
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index 2191c58..210adce 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -179,6 +179,34 @@
         return result;
     }
 
+    /*
+     * This method is added for SetupWizard, to force an update of the suggested locales
+     * when the SIM is initialized.
+     *
+     * <p>When the device is freshly started, it sometimes gets to the language selection
+     * before the SIM is properly initialized.
+     * So at the time the cache is filled, the info from the SIM might not be available.
+     * The SetupWizard has a SimLocaleMonitor class to detect onSubscriptionsChanged events.
+     * SetupWizard will call this function when that happens.</p>
+     *
+     * <p>TODO: decide if it is worth moving such kind of monitoring in this shared code.
+     * The user might change the SIM or might cross border and connect to a network
+     * in a different country, without restarting the Settings application or the phone.</p>
+     */
+    public static void updateSimCountries(Context context) {
+        Set<String> simCountries = getSimCountries(context);
+
+        for (LocaleInfo li : sLocaleCache.values()) {
+            // This method sets the suggestion flags for the (new) SIM locales, but it does not
+            // try to clean up the old flags. After all, if the user replaces a German SIM
+            // with a French one, it is still possible that they are speaking German.
+            // So both French and German are reasonable suggestions.
+            if (simCountries.contains(li.getLocale().getCountry())) {
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            }
+        }
+    }
+
     public static void fillCache(Context context) {
         if (sFullyInitialized) {
             return;
@@ -242,11 +270,11 @@
     /**
      * Returns a list of locales for language or region selection.
      * If the parent is null, then it is the language list.
-     * If it is not null, then the list will contain all the locales that belong to that perent.
+     * If it is not null, then the list will contain all the locales that belong to that parent.
      * Example: if the parent is "ar", then the region list will contain all Arabic locales.
      * (this is not language based, but language-script, so that it works for zh-Hant and so on.
      */
-    /* package */ static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
+    public static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
             LocaleInfo parent, boolean translatedOnly) {
         fillCache(context);
         String parentId = parent == null ? null : parent.getId();
diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
index 2f855c6..c4ec714 100644
--- a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
+++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
@@ -45,7 +45,7 @@
  * countries for all the other German locales, but not Switzerland
  * (Austria, Belgium, Germany, Liechtenstein, Luxembourg)</p>
  */
-class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
+public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
     private static final int TYPE_HEADER_SUGGESTED = 0;
     private static final int TYPE_HEADER_ALL_OTHERS = 1;
     private static final int TYPE_LOCALE = 2;
@@ -56,7 +56,7 @@
     private final boolean mCountryMode;
     private LayoutInflater mInflater;
 
-    SuggestedLocaleAdapter(Set<LocaleStore.LocaleInfo> localeOptions, boolean countryMode) {
+    public SuggestedLocaleAdapter(Set<LocaleStore.LocaleInfo> localeOptions, boolean countryMode) {
         mCountryMode = countryMode;
         mLocaleOptions = new ArrayList<>(localeOptions.size());
         for (LocaleStore.LocaleInfo li : localeOptions) {
@@ -169,11 +169,14 @@
         return convertView;
     }
 
-
     private boolean showHeaders() {
         return mSuggestionCount != 0 && mSuggestionCount != mLocaleOptions.size();
     }
 
+    /**
+     * Sorts the items in the adapter using a locale-aware comparator.
+     * @param comp The locale-aware comparator to use.
+     */
     public void sort(LocaleHelper.LocaleInfoComparator comp) {
         Collections.sort(mLocaleOptions, comp);
     }
@@ -222,7 +225,7 @@
 
         // TODO: decide if this is enough, or we want to use a BreakIterator...
         boolean wordMatches(String valueText, String prefixString) {
-            // First match against the whole, non-splitted value
+            // First match against the whole, non-split value
             if (valueText.startsWith(prefixString)) {
                 return true;
             }
@@ -239,7 +242,6 @@
         }
 
         @Override
-        @SuppressWarnings("unchecked")
         protected void publishResults(CharSequence constraint, FilterResults results) {
             mLocaleOptions = (ArrayList<LocaleStore.LocaleInfo>) results.values;