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

Commit f278a87b authored by Muhammed Siju's avatar Muhammed Siju Committed by Gerrit Code Review
Browse files

Fix LTE attach issue due to wrong initial attach profile.

When SIM cards are changed, the attach profile set in modem is
not changed until data is registered. Some times this leads to
permanent LTE attach failure on LTE only networks.
To fix this, de couple set initial attach apn from the setup data call
apn list. Initial attach apn is always queried from 3GPP sim
records as it is applicable only for LTE attach.
DcTracker registers with 3GPP Iccrecords for records loaded event
exclusively for setting initial attach apn.
This makes set initial attach apn operation depend only on sim
records loaded event irrespective of the data registration state.

Change-Id: I4d7b1fe32f7c2ac1b5b0672e7c03bb489d8de596
CRs-Fixed: 740330
(cherry picked from commit 881e0cb8)
Addresses CYNGNOS-665
parent 00129834
Loading
Loading
Loading
Loading
+85 −4
Original line number Diff line number Diff line
@@ -188,6 +188,25 @@ public final class DcTracker extends DcTrackerBase {
    /* IWLAN and WWAN co-exist flag */
    private boolean mWwanIwlanCoexistFlag = false;

    private static final int EVENT_3GPP_RECORDS_LOADED = 100;

    Handler mSimRecordsLoadedHandler = new Handler() {
        @Override
        public void handleMessage (Message msg) {
            if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
                loge("Sim handler handleMessage: Ignore msgs since phone is inactive");
                return;
            }

            switch (msg.what) {
                case EVENT_3GPP_RECORDS_LOADED:
                    log("EVENT_3GPP_RECORDS_LOADED");
                    onSimRecordsLoaded();
                    break;
            }
        }
    };

    private CdmaApnProfileTracker mOmhApt;

    /* MMS Data Profile Device Override */
@@ -319,6 +338,11 @@ public final class DcTracker extends DcTrackerBase {
            r.unregisterForRecordsLoaded(this);
            mIccRecords.set(null);
        }
        r = mSimRecords.get();
        if (r != null) {
            r.unregisterForRecordsLoaded(mSimRecordsLoadedHandler);
            mSimRecords.set(null);
        }
        mPhone.mCi.unregisterForDataNetworkStateChanged(this);
        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
@@ -1323,10 +1347,9 @@ public final class DcTracker extends DcTrackerBase {
        return apn;
    }

    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
    private ArrayList<ApnSetting> createApnList(Cursor cursor, IccRecords r) {
        ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
        ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
        IccRecords r = mIccRecords.get();

        if (cursor.moveToFirst()) {
            do {
@@ -1470,6 +1493,7 @@ public final class DcTracker extends DcTrackerBase {
     */
    private void onApnChanged() {
        if (DBG) log("onApnChanged: tryRestartDataConnections");
        setInitialAttachApn(create3gppApnsList(), mSimRecords.get());
        tryRestartDataConnections(true, Phone.REASON_APN_CHANGED);
    }

@@ -1487,7 +1511,6 @@ public final class DcTracker extends DcTrackerBase {
        // match the current operator.
        if (DBG) log("tryRestartDataConnections: createAllApnList and cleanUpAllConnections");
        createAllApnList();
        setInitialAttachApn();
        if (isCleanupNeeded) {
            cleanUpAllConnections(!isDisconnected, reason);
        }
@@ -2511,7 +2534,7 @@ public final class DcTracker extends DcTrackerBase {

                if (cursor != null) {
                    if (cursor.getCount() > 0) {
                        mAllApnSettings = createApnList(cursor);
                        mAllApnSettings = createApnList(cursor, mIccRecords.get());
                    }
                    cursor.close();
                }
@@ -2544,6 +2567,30 @@ public final class DcTracker extends DcTrackerBase {
        setDataProfilesAsNeeded();
    }

    private ArrayList<ApnSetting> create3gppApnsList() {
        ArrayList<ApnSetting>  apnsList = null;
        IccRecords r = mSimRecords.get();
        String operator = (r != null) ? r.getOperatorNumeric() : "";
        if (!TextUtils.isEmpty(operator)) {
            String selection = "numeric = '" + operator + "'";
            // query only enabled apn.
            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
            selection += " and carrier_enabled = 1";
            if (DBG) log("create3gppApnList: selection=" + selection);

            Cursor cursor = mPhone.getContext().getContentResolver().query(
                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);

            if (cursor != null) {
                if (cursor.getCount() > 0) {
                    apnsList = createApnList(cursor, r);
                }
                cursor.close();
            }
        }
        return apnsList;
    }

    private void dedupeApnSettings() {
        ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();

@@ -3080,6 +3127,8 @@ public final class DcTracker extends DcTrackerBase {
            return false;
        }

        updateSimRecords();

        int dataRat = mPhone.getServiceState().getRilDataRadioTechnology();
        int appFamily = UiccController.getFamilyFromRadioTechnology(dataRat);
        IccRecords newIccRecords = getUiccRecords(appFamily);
@@ -3113,6 +3162,38 @@ public final class DcTracker extends DcTrackerBase {
        return result;
    }

    /**
     * This function updates mSimRecords reference to track the current 3GPP icc records.
     * mSimRecords is used to populate the initial attach apn for the ICC card.
     */
    private void updateSimRecords() {
        if (mUiccController == null ) {
            return;
        }

        IccRecords newSimRecords = getUiccRecords(UiccController.APP_FAM_3GPP);
        log("updateSimRecords: newSimRecords = " + newSimRecords);

        IccRecords r = mSimRecords.get();
        if (r != newSimRecords) {
            if (r != null) {
                log("Removing stale sim objects.");
                r.unregisterForRecordsLoaded(mSimRecordsLoadedHandler);
                mSimRecords.set(null);
            }
            if (newSimRecords != null) {
                log("New sim records found");
                mSimRecords.set(newSimRecords);
                newSimRecords.registerForRecordsLoaded(
                        mSimRecordsLoadedHandler, EVENT_3GPP_RECORDS_LOADED, null);
            }
        }
    }

    private void onSimRecordsLoaded() {
        setInitialAttachApn(create3gppApnsList(), mSimRecords.get());
    }

    public void update() {
        log("update sub = " + mPhone.getSubId());
        log("update(): Active DDS, register for all events now!");
+13 −5
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -195,6 +196,8 @@ public abstract class DcTrackerBase extends Handler {
    protected PhoneBase mPhone;
    protected UiccController mUiccController;
    protected AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
    // 3GPP records to use for LTE initial attach apn
    protected AtomicReference<IccRecords> mSimRecords = new AtomicReference<IccRecords>();
    protected DctConstants.Activity mActivity = DctConstants.Activity.NONE;
    protected DctConstants.State mState = DctConstants.State.IDLE;
    protected Handler mDataConnectionTracker = null;
@@ -1797,19 +1800,20 @@ public abstract class DcTrackerBase extends Handler {
        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
    }

    protected void setInitialAttachApn() {
    protected void setInitialAttachApn(ArrayList <ApnSetting> apnList, IccRecords r) {
        ApnSetting iaApnSetting = null;
        ApnSetting defaultApnSetting = null;
        ApnSetting firstApnSetting = null;
        String operator = (r != null) ? r.getOperatorNumeric(): "";

        log("setInitialApn: E mPreferredApn=" + mPreferredApn);

        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
            firstApnSetting = mAllApnSettings.get(0);
        if (apnList != null && !apnList.isEmpty()) {
            firstApnSetting = apnList.get(0);
            log("setInitialApn: firstApnSetting=" + firstApnSetting);

            // Search for Initial APN setting and the first apn that can handle default
            for (ApnSetting apn : mAllApnSettings) {
            for (ApnSetting apn : apnList) {
                // Can't use apn.canHandleType(), as that returns true for APNs that have no type.
                if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_IA) &&
                        apn.carrierEnabled) {
@@ -1836,7 +1840,7 @@ public abstract class DcTrackerBase extends Handler {
        if (iaApnSetting != null) {
            if (DBG) log("setInitialAttachApn: using iaApnSetting");
            initialAttachApnSetting = iaApnSetting;
        } else if (mPreferredApn != null) {
        } else if (mPreferredApn != null && Objects.equals(mPreferredApn.numeric, operator)) {
            if (DBG) log("setInitialAttachApn: using mPreferredApn");
            initialAttachApnSetting = mPreferredApn;
        } else if (defaultApnSetting != null) {
@@ -1858,6 +1862,10 @@ public abstract class DcTrackerBase extends Handler {
        }
    }

    protected void setInitialAttachApn() {
        setInitialAttachApn(mAllApnSettings, mIccRecords.get());
    }

    protected void setDataProfilesAsNeeded() {
        if (DBG) log("setDataProfilesAsNeeded");
        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {