Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 230e46bd authored by nfjb73's avatar nfjb73 Committed by Amit Mahajan
Browse files

add capability to initialize default locale from USIM EF_LI or EF_PL.

if user has set the defalut locale, the locale from USIM will be ignored.

Bug: 17543708
Change-Id: I1f9fa8b73b84f27ef8414bb1fc1c01b4a021c791
parent eda3c479
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -314,6 +314,7 @@ public final class MccTable
        if (locale != null) {
            Configuration config = new Configuration();
            config.setLocale(locale);
            config.userSetLocale = false;
            Slog.d(LOG_TAG, "setSystemLocale: updateLocale config=" + config);
            try {
                ActivityManagerNative.getDefault().updateConfiguration(config);
+2 −1
Original line number Diff line number Diff line
@@ -44,8 +44,9 @@ public interface IccConstants {
    static final int EF_CFIS = 0x6FCB;
    static final int EF_IMG = 0x4f20;

    // USIM SIM file ids from TS 31.102
    // USIM SIM file ids from TS 131.102
    public static final int EF_PBR = 0x4F30;
    public static final int EF_LI = 0x6F05;

    // GSM SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6
    static final int EF_MAILBOX_CPHS = 0x6F17;
+113 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.SmsConstants;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.gsm.SimTlv;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -80,6 +82,8 @@ public class SIMRecords extends IccRecords {
    byte[] mEfCff = null;
    byte[] mEfCfis = null;

    byte[] mEfLi = null;
    byte[] mEfPl = null;

    int mSpnDisplayCondition;
    // Numeric network codes listed in TS 51.011 EF[SPDI]
@@ -162,6 +166,7 @@ public class SIMRecords extends IccRecords {
    private static final int EVENT_GET_CFIS_DONE = 32;
    private static final int EVENT_GET_CSP_CPHS_DONE = 33;
    private static final int EVENT_GET_GID1_DONE = 34;
    private static final int EVENT_APP_LOCKED = 35;

    // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.

@@ -206,6 +211,7 @@ public class SIMRecords extends IccRecords {
        // Start off by setting empty state
        resetRecords();
        mParentApp.registerForReady(this, EVENT_APP_READY, null);
        mParentApp.registerForLocked(this, EVENT_APP_LOCKED, null);
        if (DBG) log("SIMRecords X ctor this=" + this);
    }

@@ -216,6 +222,7 @@ public class SIMRecords extends IccRecords {
        mCi.unregisterForIccRefresh(this);
        mCi.unSetOnSmsOnSim(this);
        mParentApp.unregisterForReady(this);
        mParentApp.unregisterForLocked(this);
        resetRecords();
        super.dispose();
    }
@@ -584,6 +591,10 @@ public class SIMRecords extends IccRecords {
                onReady();
                break;

            case EVENT_APP_LOCKED:
                onLocked();
                break;

            /* IO events */
            case EVENT_GET_IMSI_DONE:
                isRecordLoadResponse = true;
@@ -1201,6 +1212,28 @@ public class SIMRecords extends IccRecords {
        }
    }

    private class EfPlLoaded implements IccRecordLoaded {
        public String getEfName() {
            return "EF_PL";
        }

        public void onRecordLoaded(AsyncResult ar) {
            mEfPl = (byte[]) ar.result;
            if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEfPl));
        }
    }

    private class EfUsimLiLoaded implements IccRecordLoaded {
        public String getEfName() {
            return "EF_LI";
        }

        public void onRecordLoaded(AsyncResult ar) {
            mEfLi = (byte[]) ar.result;
            if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEfLi));
        }
    }

    private void handleFileUpdate(int efid) {
        switch(efid) {
            case EF_MBDN:
@@ -1341,6 +1374,56 @@ public class SIMRecords extends IccRecords {
        }
    }

    private String findBestLanguage(byte[] languages) {
        String bestMatch = null;
        String[] locales = mContext.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");
                if (DBG) log ("languages from sim = " + lang);
                for (int j = 0; j < locales.length; j++) {
                    if (locales[j] != null && locales[j].length() >= 2 &&
                            locales[j].substring(0, 2).equalsIgnoreCase(lang)) {
                        return lang;
                    }
                }
                if (bestMatch != null) break;
            } catch(java.io.UnsupportedEncodingException e) {
                log ("Failed to parse USIM language records" + e);
            }
        }
        // no match found. return null
        return null;
    }

    private void setLocaleFromUsim() {
        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)));
            }
            if (DBG) log("Setting locale to " + prefLang + "_" + country);
            MccTable.setSystemLocale(mContext, prefLang, country);
        } else {
            if (DBG) log ("No suitable USIM selected locale");
        }
    }

    @Override
    protected void onRecordLoaded() {
        // One record loaded successfully or failed, In either case
@@ -1360,6 +1443,16 @@ public class SIMRecords extends IccRecords {
    protected void onAllRecordsLoaded() {
        if (DBG) log("record load complete");

        setLocaleFromUsim();

        if (mParentApp.getState() == AppState.APPSTATE_PIN ||
               mParentApp.getState() == AppState.APPSTATE_PUK) {
            // reset recordsRequested, since sim is not loaded really
            mRecordsRequested = false;
            // lock state, only update language
            return ;
        }

        // Some fields require more than one SIM record to set

        String operator = getOperatorNumeric();
@@ -1411,6 +1504,24 @@ public class SIMRecords extends IccRecords {
        fetchSimRecords();
    }

    private void onLocked() {
        mRecordsRequested = true;
        if (DBG) log("only fetch EF_LI and EF_PL in lock state");
        loadEfLiAndEfPl();
    }

    private void loadEfLiAndEfPl() {
        if (mParentApp.getType() == AppType.APPTYPE_USIM) {
            mFh.loadEFTransparent(EF_LI,
                    obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfUsimLiLoaded()));
            mRecordsToLoad++;

            mFh.loadEFTransparent(EF_PL,
                    obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded()));
            mRecordsToLoad++;
        }
    }

    protected void fetchSimRecords() {
        mRecordsRequested = true;

@@ -1477,6 +1588,8 @@ public class SIMRecords extends IccRecords {
        mFh.loadEFTransparent(EF_GID1, obtainMessage(EVENT_GET_GID1_DONE));
        mRecordsToLoad++;

        loadEfLiAndEfPl();

        // XXX should seek instead of examining them all
        if (false) { // XXX
            mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ public final class UsimFileHandler extends IccFileHandler implements IccConstant
        case EF_INFO_CPHS:
        case EF_CSP_CPHS:
        case EF_GID1:
        case EF_LI:
            return MF_SIM + DF_ADF;

        case EF_PBR: