Merge "Set locale based on SIM preferred language." into honeycomb-LTE
diff --git a/telephony/java/com/android/internal/telephony/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java
index fde1b59..cdce841 100644
--- a/telephony/java/com/android/internal/telephony/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/MccTable.java
@@ -234,7 +234,7 @@
         String country = MccTable.countryCodeForMcc(mcc);
 
         Log.d(LOG_TAG, "locale set to "+language+"_"+country);
-        phone.setSystemLocale(language, country);
+        phone.setSystemLocale(language, country, true);
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index f70d680..40a70a8 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -580,7 +580,7 @@
                 if (l.length() >=5) {
                     country = l.substring(3, 5);
                 }
-                setSystemLocale(language, country);
+                setSystemLocale(language, country, false);
 
                 if (!country.isEmpty()) {
                     try {
@@ -602,10 +602,14 @@
      * Utility code to set the system locale if it's not set already
      * @param language Two character language code desired
      * @param country Two character country code desired
+     * @param fromMcc Indicating whether the locale is set according to MCC table.
+     *                This flag wil be ignored by default implementation.
+     *                TODO: Use a source enumeration so that source of the locale
+     *                      can be prioritized.
      *
      *  {@hide}
      */
-    public void setSystemLocale(String language, String country) {
+    public void setSystemLocale(String language, String country, boolean fromMcc) {
         String l = SystemProperties.get("persist.sys.language");
         String c = SystemProperties.get("persist.sys.country");
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index 518a34a..6a95b67 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -121,6 +121,15 @@
     }
 
     @Override
+    public void setSystemLocale(String language, String country, boolean fromMcc) {
+        // Avoid system locale is set from MCC table if CDMALTEPhone is used.
+        // The locale will be picked up based on EFpl/EFli once CSIM records are loaded.
+        if (fromMcc) return;
+
+        super.setSystemLocale(language, country, false);
+    }
+
+    @Override
     protected void log(String s) {
         if (DBG)
             Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index ac77f9a..58ef747 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -19,6 +19,7 @@
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.IccFileHandler;
 import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.MccTable;
 import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.cdma.sms.UserData;
 import com.android.internal.telephony.gsm.SIMRecords;
@@ -185,6 +186,12 @@
     }
 
     @Override
+    protected void onAllRecordsLoaded() {
+        super.onAllRecordsLoaded();
+        setLocaleFromCsim();
+    }
+
+    @Override
     protected void fetchSimRecords() {
         IccFileHandler iccFh = phone.getIccFileHandler();
         recordsRequested = true;
@@ -355,12 +362,58 @@
         if (DBG) log("CSIM PRL version=" + mPrlVersion);
     }
 
-    public byte[] getPreferredLanguage() {
-        return mEFpl;
+    private void setLocaleFromCsim() {
+        String prefLang = null;
+        // check EFli then EFpl
+        prefLang = findBestLanguage(mEFli);
+
+        if (prefLang == null) {
+            prefLang = findBestLanguage(mEFpl);
+        }
+
+        if (prefLang != null) {
+            // check country code from SIM
+            String imsi = getIMSI();
+            String country = null;
+            if (imsi != null) {
+                country = MccTable.countryCodeForMcc(
+                                    Integer.parseInt(imsi.substring(0,3)));
+            }
+            log("Setting locale to " + prefLang + "_" + country);
+            phone.setSystemLocale(prefLang, country, false);
+        } else {
+            log ("No suitable CSIM selected locale");
+        }
     }
 
-    public byte[] getLanguageIndication() {
-        return mEFli;
+    private String findBestLanguage(byte[] languages) {
+        String bestMatch = null;
+        String[] locales = phone.getContext().getAssets().getLocales();
+
+        if ((languages == null) || (locales == null)) return null;
+
+        // Each 2-bytes consists of one language
+        for (int i = 0; (i + 1) < languages.length; i += 2) {
+            try {
+                String lang = new String(languages, i, 2, "ISO-8859-1");
+                for (int j = 0; j < locales.length; j++) {
+                    if (locales[j] != null && locales[j].length() >= 2 &&
+                        locales[j].substring(0, 2).equals(lang)) {
+                        return lang;
+                    }
+                }
+                if (bestMatch != null) break;
+            } catch(java.io.UnsupportedEncodingException e) {
+                log ("Failed to parse SIM language records");
+            }
+        }
+        // no match found. return null
+        return null;
+    }
+
+    @Override
+    protected void log(String s) {
+        if (DBG) Log.d(LOG_TAG, "[CSIM] " + s);
     }
 
     public String getMdn() {