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

Commit 7cd6a99e authored by Alex Yakavenka's avatar Alex Yakavenka Committed by Gerrit Code Review
Browse files

Fix cdma data calls based on NV

For NV data calls we need to create dummy profiles
When DcTracker switches from lte to cdma we need to bring
down existing data call and establish new one (same goes
for switching cdma->lte)

Bug: 10804691
Change-Id: I7ad8d0632854ea9875afb76709c1ba894bf048fd
(cherry picked from commit 4ead798ed4964952c3086b3224d775479d66d240)
(cherry picked from commit f333f0ca7b1c992ab36af83ca74a1131d3ae17b8)
(cherry picked from commit 14e5657432de2eb9ba52ebf28a8967ed62ee4a0b)
parent d6127d03
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,7 @@ public interface Phone {
    static final String REASON_LOST_DATA_CONNECTION = "lostDataConnection";
    static final String REASON_LOST_DATA_CONNECTION = "lostDataConnection";
    static final String REASON_CONNECTED = "connected";
    static final String REASON_CONNECTED = "connected";
    static final String REASON_SINGLE_PDN_ARBITRATION = "SinglePdnArbitration";
    static final String REASON_SINGLE_PDN_ARBITRATION = "SinglePdnArbitration";
    static final String REASON_NV_READY = "nvReady";


    // Used for band mode selection methods
    // Used for band mode selection methods
    static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
    static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
+2 −1
Original line number Original line Diff line number Diff line
@@ -136,7 +136,8 @@ public class CDMAPhone extends PhoneBase {


    Registrant mPostDialHandler;
    Registrant mPostDialHandler;


    static String PROPERTY_CDMA_HOME_OPERATOR_NUMERIC = "ro.cdma.home.operator.numeric";
    public static final String PROPERTY_CDMA_HOME_OPERATOR_NUMERIC =
            "ro.cdma.home.operator.numeric";


    // Constructors
    // Constructors
    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
+9 −4
Original line number Original line Diff line number Diff line
@@ -455,10 +455,11 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
            mPhone.notifyServiceStateChanged(mSS);
            mPhone.notifyServiceStateChanged(mSS);
        }
        }


        if (hasCdmaDataConnectionAttached || has4gHandoff) {
        // First notify detached, then rat changed, then attached - that's the way it
            mAttachedRegistrants.notifyRegistrants();
        // happens in the modem.
        }
        // Behavior of recipients (DcTracker, for instance) depends on this sequence

        // since DcTracker reloads profiles on "rat_changed" notification and sets up
        // data call on "attached" notification.
        if (hasCdmaDataConnectionDetached) {
        if (hasCdmaDataConnectionDetached) {
            mDetachedRegistrants.notifyRegistrants();
            mDetachedRegistrants.notifyRegistrants();
        }
        }
@@ -468,6 +469,10 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
            mPhone.notifyDataConnection(null);
            mPhone.notifyDataConnection(null);
        }
        }


        if (hasCdmaDataConnectionAttached || has4gHandoff) {
            mAttachedRegistrants.notifyRegistrants();
        }

        if (hasRoamingOn) {
        if (hasRoamingOn) {
            mRoamingOnRegistrants.notifyRegistrants();
            mRoamingOnRegistrants.notifyRegistrants();
        }
        }
+9 −4
Original line number Original line Diff line number Diff line
@@ -1107,10 +1107,11 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
            mPhone.notifyServiceStateChanged(mSS);
            mPhone.notifyServiceStateChanged(mSS);
        }
        }


        if (hasCdmaDataConnectionAttached) {
        // First notify detached, then rat changed, then attached - that's the way it
            mAttachedRegistrants.notifyRegistrants();
        // happens in the modem.
        }
        // Behavior of recipients (DcTracker, for instance) depends on this sequence

        // since DcTracker reloads profiles on "rat_changed" notification and sets up
        // data call on "attached" notification.
        if (hasCdmaDataConnectionDetached) {
        if (hasCdmaDataConnectionDetached) {
            mDetachedRegistrants.notifyRegistrants();
            mDetachedRegistrants.notifyRegistrants();
        }
        }
@@ -1120,6 +1121,10 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
            mPhone.notifyDataConnection(null);
            mPhone.notifyDataConnection(null);
        }
        }


        if (hasCdmaDataConnectionAttached) {
            mAttachedRegistrants.notifyRegistrants();
        }

        if (hasRoamingOn) {
        if (hasRoamingOn) {
            mRoamingOnRegistrants.notifyRegistrants();
            mRoamingOnRegistrants.notifyRegistrants();
        }
        }
+128 −30
Original line number Original line Diff line number Diff line
@@ -58,6 +58,8 @@ import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.IccRecords;
@@ -113,6 +115,8 @@ public final class DcTracker extends DcTrackerBase {
    /** Watches for changes to the APN db. */
    /** Watches for changes to the APN db. */
    private ApnChangeObserver mApnObserver;
    private ApnChangeObserver mApnObserver;


    private CdmaSubscriptionSourceManager mCdmaSsm;

    //***** Constructor
    //***** Constructor


    public DcTracker(PhoneBase p) {
    public DcTracker(PhoneBase p) {
@@ -138,6 +142,16 @@ public final class DcTracker extends DcTrackerBase {
                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
                DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
        p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
        p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
                DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
        p.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
                DctConstants.EVENT_DATA_RAT_CHANGED, null);

        if (p.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
            mCdmaSsm = CdmaSubscriptionSourceManager.getInstance(
                    p.getContext(), p.mCi, this,
                    DctConstants.EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
            // CdmaSsm doesn't send this event whenever you register - fake it ourselves
            sendMessage(obtainMessage(DctConstants.EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED));
        }


        mDataConnectionTracker = this;
        mDataConnectionTracker = this;


@@ -169,7 +183,7 @@ public final class DcTracker extends DcTrackerBase {


    @Override
    @Override
    public void dispose() {
    public void dispose() {
        if (DBG) log("GsmDCT.dispose");
        if (DBG) log("dispose");
        cleanUpAllConnections(true, null);
        cleanUpAllConnections(true, null);


        super.dispose();
        super.dispose();
@@ -193,6 +207,9 @@ public final class DcTracker extends DcTrackerBase {
        mApnContexts.clear();
        mApnContexts.clear();
        mPrioritySortedApnContexts.clear();
        mPrioritySortedApnContexts.clear();


        if (mCdmaSsm != null) {
            mCdmaSsm.dispose(this);
        }
        destroyDataConnections();
        destroyDataConnections();
    }
    }


@@ -574,10 +591,11 @@ public final class DcTracker extends DcTrackerBase {
        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
        IccRecords r = mIccRecords.get();
        IccRecords r = mIccRecords.get();
        boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
        boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
        boolean subscriptionFromNv = isNvSubscription();


        boolean allowed =
        boolean allowed =
                    (attachedState || mAutoAttachOnCreation) &&
                    (attachedState || mAutoAttachOnCreation) &&
                    recordsLoaded &&
                    (subscriptionFromNv || recordsLoaded) &&
                    (mPhone.getState() == PhoneConstants.State.IDLE ||
                    (mPhone.getState() == PhoneConstants.State.IDLE ||
                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
                    internalDataEnabled &&
                    internalDataEnabled &&
@@ -589,7 +607,9 @@ public final class DcTracker extends DcTrackerBase {
            if (!(attachedState || mAutoAttachOnCreation)) {
            if (!(attachedState || mAutoAttachOnCreation)) {
                reason += " - Attached= " + attachedState;
                reason += " - Attached= " + attachedState;
            }
            }
            if (!recordsLoaded) reason += " - SIM not loaded";
            if (!(subscriptionFromNv || recordsLoaded)) {
                reason += " - SIM not loaded and not NV subscription";
            }
            if (mPhone.getState() != PhoneConstants.State.IDLE &&
            if (mPhone.getState() != PhoneConstants.State.IDLE &&
                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
                reason += " - PhoneState= " + mPhone.getState();
                reason += " - PhoneState= " + mPhone.getState();
@@ -1110,6 +1130,11 @@ public final class DcTracker extends DcTrackerBase {
     * Handles changes to the APN database.
     * Handles changes to the APN database.
     */
     */
    private void onApnChanged() {
    private void onApnChanged() {
        if (DBG) log("onApnChanged: tryRestartDataConnections");
        tryRestartDataConnections(Phone.REASON_APN_CHANGED);
    }

    private void tryRestartDataConnections(String reason) {
        DctConstants.State overallState = getOverallState();
        DctConstants.State overallState = getOverallState();
        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
        boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
                overallState == DctConstants.State.FAILED);
                overallState == DctConstants.State.FAILED);
@@ -1121,12 +1146,12 @@ public final class DcTracker extends DcTrackerBase {


        // TODO: It'd be nice to only do this if the changed entrie(s)
        // TODO: It'd be nice to only do this if the changed entrie(s)
        // match the current operator.
        // match the current operator.
        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
        if (DBG) log("tryRestartDataConnections: createAllApnList and cleanUpAllConnections");
        createAllApnList();
        createAllApnList();
        setInitialAttachApn();
        setInitialAttachApn();
        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
        cleanUpAllConnections(!isDisconnected, reason);
        if (isDisconnected) {
        if (isDisconnected) {
            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
            setupDataOnConnectableApns(reason);
        }
        }
    }
    }


@@ -1342,6 +1367,12 @@ public final class DcTracker extends DcTrackerBase {
        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
    }
    }


    private void onNvReady() {
        if (DBG) log("onNvReady");
        createAllApnList();
        setupDataOnConnectableApns(Phone.REASON_NV_READY);
    }

    @Override
    @Override
    protected void onSetDependencyMet(String apnType, boolean met) {
    protected void onSetDependencyMet(String apnType, boolean met) {
        // don't allow users to tweak hipri to work around default dependency not met
        // don't allow users to tweak hipri to work around default dependency not met
@@ -1854,12 +1885,17 @@ public final class DcTracker extends DcTrackerBase {


        // If APN is still enabled, try to bring it back up automatically
        // If APN is still enabled, try to bring it back up automatically
        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
        if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
            if (apnContext.getReason().equals(Phone.REASON_NW_TYPE_CHANGED)) {
                // Retry immediately if reason is nw_type_changed (like rat switch, for instance)
                setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED);
            } else {
                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
                SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
                // Wait a bit before trying the next APN, so that
                // Wait a bit before trying the next APN, so that
                // we're not tying up the RIL command channel.
                // we're not tying up the RIL command channel.
                // This also helps in any external dependency to turn off the context.
                // This also helps in any external dependency to turn off the context.
                if(DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
                if(DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
                startAlarmForReconnect(getApnDelay(), apnContext);
                startAlarmForReconnect(getApnDelay(), apnContext);
            }
        } else {
        } else {
            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
@@ -1985,14 +2021,43 @@ public final class DcTracker extends DcTrackerBase {
        notifyOffApnsOfAvailability(reason);
        notifyOffApnsOfAvailability(reason);
    }
    }


    private boolean isNvSubscription() {
        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
        if (mCdmaSsm == null) {
            return false;
        }
        if (UiccController.getFamilyFromRadioTechnology(radioTech) == UiccController.APP_FAM_3GPP2
                && mCdmaSsm.getCdmaSubscriptionSource() ==
                        CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV) {
            return true;
        }
        return false;
    }

    /**
    /**
     * Based on the sim operator numeric, create a list for all possible
     * Returns mccmnc for data call either from cdma_home_operator or from IccRecords
     * @return operator numeric
     */
    private String getOperatorNumeric() {
        String result;
        if (isNvSubscription()) {
            result = SystemProperties.get(CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC);
            log("getOperatorNumberic - returning from NV: " + result);
        } else {
            IccRecords r = mIccRecords.get();
            result = (r != null) ? r.getOperatorNumeric() : "";
            log("getOperatorNumberic - returning from card: " + result);
        }
        return result;
    }

    /**
     * Based on the operator numeric, create a list for all possible
     * Data Connections and setup the preferredApn.
     * Data Connections and setup the preferredApn.
     */
     */
    private void createAllApnList() {
    private void createAllApnList() {
        mAllApnSettings = new ArrayList<ApnSetting>();
        mAllApnSettings = new ArrayList<ApnSetting>();
        IccRecords r = mIccRecords.get();
        String operator = getOperatorNumeric();
        String operator = (r != null) ? r.getOperatorNumeric() : "";
        if (operator != null) {
        if (operator != null) {
            String selection = "numeric = '" + operator + "'";
            String selection = "numeric = '" + operator + "'";
            // query only enabled apn.
            // query only enabled apn.
@@ -2076,9 +2141,7 @@ public final class DcTracker extends DcTrackerBase {
            }
            }
        }
        }


        IccRecords r = mIccRecords.get();
        String operator = getOperatorNumeric();
        String operator = (r != null) ? r.getOperatorNumeric() : "";

        // This is a workaround for a bug (7305641) where we don't failover to other
        // This is a workaround for a bug (7305641) where we don't failover to other
        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
        // suitable APNs if our preferred APN fails.  On prepaid ATT sims we need to
        // failover to a provisioning APN, but once we've used their default data
        // failover to a provisioning APN, but once we've used their default data
@@ -2096,8 +2159,7 @@ public final class DcTracker extends DcTrackerBase {
            log("buildWaitingApns: usePreferred=" + usePreferred
            log("buildWaitingApns: usePreferred=" + usePreferred
                    + " canSetPreferApn=" + mCanSetPreferApn
                    + " canSetPreferApn=" + mCanSetPreferApn
                    + " mPreferredApn=" + mPreferredApn
                    + " mPreferredApn=" + mPreferredApn
                    + " operator=" + operator + " radioTech=" + radioTech
                    + " operator=" + operator + " radioTech=" + radioTech);
                    + " IccRecords r=" + r);
        }
        }


        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
        if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
@@ -2122,7 +2184,7 @@ public final class DcTracker extends DcTrackerBase {
                mPreferredApn = null;
                mPreferredApn = null;
            }
            }
        }
        }
        if (mAllApnSettings != null) {
        if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
            if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
            for (ApnSetting apn : mAllApnSettings) {
            for (ApnSetting apn : mAllApnSettings) {
                if (DBG) log("buildWaitingApns: apn=" + apn);
                if (DBG) log("buildWaitingApns: apn=" + apn);
@@ -2319,6 +2381,20 @@ public final class DcTracker extends DcTrackerBase {
                }
                }
                break;
                break;


            case DctConstants.EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: // fall thru
            case DctConstants.EVENT_DATA_RAT_CHANGED:
                // When data rat changes we might need to load different
                // set of apns (example, LTE->1x)
                if (onUpdateIcc()) {
                    log("onUpdateIcc: tryRestartDataConnections " + Phone.REASON_NW_TYPE_CHANGED);
                    tryRestartDataConnections(Phone.REASON_NW_TYPE_CHANGED);
                } else if (isNvSubscription()){
                    // If cdma subscription source changed to NV or data rat changed to cdma
                    // (while subscription source was NV) - we need to trigger NV ready
                    onNvReady();
                }
                break;

            default:
            default:
                // handle the message in the super class DataConnectionTracker
                // handle the message in the super class DataConnectionTracker
                super.handleMessage(msg);
                super.handleMessage(msg);
@@ -2356,28 +2432,50 @@ public final class DcTracker extends DcTrackerBase {
        return cid;
        return cid;
    }
    }


    /**
     * @description This function updates mIccRecords reference to track
     *              currently used IccRecords
     * @return true if IccRecords changed
     */
    @Override
    @Override
    protected void onUpdateIcc() {
    protected boolean onUpdateIcc() {
        boolean result = false;
        if (mUiccController == null ) {
        if (mUiccController == null ) {
            return;
            loge("onUpdateIcc: mUiccController is null. Error!");
            return false;
        }
        }


        IccRecords newIccRecords = mUiccController.getIccRecords(UiccController.APP_FAM_3GPP);
        int dataRat = mPhone.getServiceState().getRilDataRadioTechnology();
        int appFamily = UiccController.getFamilyFromRadioTechnology(dataRat);
        IccRecords newIccRecords = mUiccController.getIccRecords(appFamily);
        log("onUpdateIcc: newIccRecords " + ((newIccRecords != null) ?
                newIccRecords.getClass().getName() : null));
        if (dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
            // Ignore this. This could be due to data not registered
            // We want to ignore RADIO_TECHNOLOGY_UNKNOWN so that we do not tear down data
            // call in case we are out of service.
            return false;
        }


        IccRecords r = mIccRecords.get();
        IccRecords r = mIccRecords.get();
        if (r != newIccRecords) {
        if (r != newIccRecords) {
            if (r != null) {
            if (r != null) {
                log("Removing stale icc objects.");
                log("Removing stale icc objects. " + ((r != null) ?
                        r.getClass().getName() : null));
                r.unregisterForRecordsLoaded(this);
                r.unregisterForRecordsLoaded(this);
                mIccRecords.set(null);
                mIccRecords.set(null);
            }
            }
            if (newIccRecords != null) {
            if (newIccRecords != null) {
                log("New records found");
                log("New records found " + ((newIccRecords != null) ?
                        newIccRecords.getClass().getName() : null));
                mIccRecords.set(newIccRecords);
                mIccRecords.set(newIccRecords);
                newIccRecords.registerForRecordsLoaded(
                newIccRecords.registerForRecordsLoaded(
                        this, DctConstants.EVENT_RECORDS_LOADED, null);
                        this, DctConstants.EVENT_RECORDS_LOADED, null);
            }
            }
            // Records changed -> return true
            result = true;
        }
        }
        return result;
    }
    }


    @Override
    @Override
Loading