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

Commit a412838a authored by Amit Mahajan's avatar Amit Mahajan Committed by Gerrit Code Review
Browse files

Merge "Data connection for carrier specific APN"

parents 120d9d06 249adbcc
Loading
Loading
Loading
Loading
+140 −23
Original line number Diff line number Diff line
@@ -1784,29 +1784,109 @@ public class DcTracker extends Handler {
        if (DBG) log(str + " apnContext=" + apnContext + " dc=" + apnContext.getDataConnection());
    }

    private Cursor getPreferredApnCursor(int subId) {
        Cursor cursor = null;
        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            cursor = mPhone.getContext().getContentResolver().query(
                    Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID,
                            String.valueOf(subId)), null, null, null,
                    Telephony.Carriers.DEFAULT_SORT_ORDER);
        }
        return cursor;
    }

    private ApnSetting getPreferredApnFromDB() {
        ApnSetting preferredApn = null;
        Cursor cursor = getPreferredApnCursor(mPhone.getSubId());
        if (cursor != null) {
            if (cursor.getCount() > 0) {
                cursor.moveToFirst();
                preferredApn = ApnSetting.makeApnSetting(cursor);
            }
            cursor.close();
        }
        if (VDBG) log("getPreferredApnFromDB: preferredApn=" + preferredApn);
        return preferredApn;
    }

    private void setDefaultPreferredApnIfNeeded() {
        ApnSetting defaultPreferredApn = null;
        PersistableBundle bundle = getCarrierConfig();
        String defaultPreferredApnName = bundle.getString(CarrierConfigManager
                .KEY_DEFAULT_PREFERRED_APN_NAME_STRING);

        if (TextUtils.isEmpty(defaultPreferredApnName) || getPreferredApnFromDB() != null) {
            return;
        }

        String selection = Telephony.Carriers.APN + " = \"" + defaultPreferredApnName + "\" AND "
                + Telephony.Carriers.EDITED_STATUS + " = " + Telephony.Carriers.UNEDITED;
        Cursor cursor = mPhone.getContext().getContentResolver().query(
                Uri.withAppendedPath(Telephony.Carriers.SIM_APN_URI,
                        "filtered/subId/" + mPhone.getSubId()),
                null, selection, null, Telephony.Carriers._ID);

        if (cursor != null) {
            if (cursor.getCount() > 0) {
                if (cursor.moveToFirst()) {
                    defaultPreferredApn = ApnSetting.makeApnSetting(cursor);
                }
            }
            cursor.close();
        }

        if (defaultPreferredApn != null
                && defaultPreferredApn.canHandleType(mRequestedApnType)) {
            log("setDefaultPreferredApnIfNeeded: For APN type "
                    + ApnSetting.getApnTypeString(mRequestedApnType)
                    + " found default apnSetting "
                    + defaultPreferredApn);

            setPreferredApn(defaultPreferredApn.getId(), true);
        }

        return;
    }

    /**
     * Check if preferred apn is allowed to edit by user.
     * @return {@code true} if it is allowed to edit.
     */
    @VisibleForTesting
    public boolean isPreferredApnUserEdited() {
        boolean isUserEdited = false;
        Cursor cursor = getPreferredApnCursor(mPhone.getSubId());
        if (cursor != null) {
            if (cursor.getCount() > 0) {
                if (cursor.moveToFirst()) {
                    isUserEdited = cursor.getInt(
                            cursor.getColumnIndexOrThrow(Telephony.Carriers.EDITED_STATUS))
                            == Telephony.Carriers.USER_EDITED;
                }
            }
            cursor.close();
        }
        if (VDBG) log("isPreferredApnUserEdited: isUserEdited=" + isUserEdited);
        return isUserEdited;
    }

    /**
     * Fetch the DUN apns
     * @return a list of DUN ApnSetting objects
     */
    @VisibleForTesting
    public @NonNull ArrayList<ApnSetting> fetchDunApns() {
        if (mPhone.getServiceState().getRoaming() && !isPreferredApnUserEdited()
                && getCarrierConfig().getBoolean(CarrierConfigManager
                .KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL)) {
            if (VDBG) log("fetchDunApns: Dun apn is not used in roaming network");
            return new ArrayList<ApnSetting>(0);
        }

        int bearer = getDataRat();
        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
        ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();

        if (mPhone.getServiceState().getRoaming()) {
            CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
                    .getSystemService(Context.CARRIER_CONFIG_SERVICE);
            if (configManager != null) {
                PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
                if (b != null) {
                    if (b.getBoolean(CarrierConfigManager.KEY_DISABLE_DUN_APN_WHILE_ROAMING)) {
                        return new ArrayList<>();
                    }
                }
            }
        }

        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
        // APN database
        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
@@ -1826,12 +1906,11 @@ public class DcTracker extends Handler {
            }
        }

        int preferredApnSetId = getPreferredApnSetId();
        for (ApnSetting dunSetting : dunCandidates) {
            if (dunSetting.canSupportNetworkType(
                    ServiceState.rilRadioTechnologyToNetworkType(bearer))) {
                int preferredApnSetId = getPreferredApnSetId();
                if (preferredApnSetId == Telephony.Carriers.NO_APN_SET_ID
                        || preferredApnSetId == dunSetting.getApnSetId()) {
                if (preferredApnSetId == dunSetting.getApnSetId()) {
                    retDunSettings.add(dunSetting);
                }
            }
@@ -2054,7 +2133,15 @@ public class DcTracker extends Handler {
              iaApnSetting = mPreferredApn;
        } else if (!mAllApnSettings.isEmpty()) {
            // Search for Initial APN setting and the first apn that can handle default
            int preferredApnSetId = getPreferredApnSetId();
            for (ApnSetting apn : mAllApnSettings) {
                if (preferredApnSetId != apn.getApnSetId()) {
                    if (VDBG) {
                        log("setInitialApn: APN set id " + apn.getApnSetId()
                                + " does not match the preferred set id " + preferredApnSetId);
                    }
                    continue;
                }
                if (firstNonEmergencyApnSetting == null
                        && !apn.isEmergencyApn()) {
                    firstNonEmergencyApnSetting = apn;
@@ -2129,6 +2216,7 @@ public class DcTracker extends Handler {
        // TODO: It'd be nice to only do this if the changed entrie(s)
        // match the current operator.
        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
        setDefaultPreferredApnIfNeeded();
        createAllApnList();
        setDataProfilesAsNeeded();
        setInitialAttachApn();
@@ -2275,6 +2363,7 @@ public class DcTracker extends Handler {

        mAutoAttachEnabled.set(false);
        setDefaultDataRoamingEnabled();
        setDefaultPreferredApnIfNeeded();
        read5GConfiguration();
        registerSettingsObserver();
        mConfigReady = true;
@@ -3155,11 +3244,20 @@ public class DcTracker extends Handler {

        ArrayList<DataProfile> dataProfileList = new ArrayList<>();

        int preferredApnSetId = getPreferredApnSetId();
        for (ApnSetting apn : mAllApnSettings) {
            if (apn.getApnSetId() == Telephony.Carriers.MATCH_ALL_APN_SET_ID
                    || preferredApnSetId == apn.getApnSetId()) {
                DataProfile dp = createDataProfile(apn, apn.equals(getPreferredApn()));
                if (!dataProfileList.contains(dp)) {
                    dataProfileList.add(dp);
                }
            } else {
                if (VDBG) {
                    log("setDataProfilesAsNeeded: APN set id " + apn.getApnSetId()
                            + " does not match the preferred set id " + preferredApnSetId);
                }
            }
        }

        // Check if the data profiles we are sending are same as we did last time. We don't want to
@@ -3367,13 +3465,12 @@ public class DcTracker extends Handler {
        }

        if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
        int preferredApnSetId = getPreferredApnSetId();
        for (ApnSetting apn : mAllApnSettings) {
            if (apn.canHandleType(requestedApnTypeBitmask)) {
                if (apn.canSupportNetworkType(
                        ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
                    int preferredApnSetId = getPreferredApnSetId();
                    if (apn.isEmergencyApn()
                            || preferredApnSetId == Telephony.Carriers.NO_APN_SET_ID
                    if (apn.getApnSetId() == Telephony.Carriers.MATCH_ALL_APN_SET_ID
                            || preferredApnSetId == apn.getApnSetId()) {
                        if (VDBG) log("buildWaitingApns: adding apn=" + apn);
                        apnList.add(apn);
@@ -3410,7 +3507,11 @@ public class DcTracker extends Handler {
    }

    private void setPreferredApn(int pos) {
        if (!mCanSetPreferApn) {
        setPreferredApn(pos, false);
    }

    private void setPreferredApn(int pos, boolean force) {
        if (!force && !mCanSetPreferApn) {
            log("setPreferredApn: X !canSEtPreferApn");
            return;
        }
@@ -4320,6 +4421,7 @@ public class DcTracker extends Handler {
                .setApnName("sos")
                .setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY)
                .setCarrierEnabled(true)
                .setApnSetId(Telephony.Carriers.MATCH_ALL_APN_SET_ID)
                .build();
    }

@@ -5140,4 +5242,19 @@ public class DcTracker extends Handler {
    public void unregisterForPhysicalLinkStateChanged(Handler h) {
        mDcc.unregisterForPhysicalLinkStateChanged(h);
    }

    @NonNull
    private PersistableBundle getCarrierConfig() {
        CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (configManager != null) {
            // If an invalid subId is used, this bundle will contain default values.
            PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId());
            if (config != null) {
                return config;
            }
        }
        // Return static default defined in CarrierConfigManager.
        return CarrierConfigManager.getDefaultConfig();
    }
}
+21 −2
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -458,6 +459,16 @@ public class DcTrackerTest extends TelephonyTest {
            mPreferredApnSet = values.getAsInteger(Telephony.Carriers.APN_SET_ID);
            return 1;
        }

        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            return 0;
        }

        @Override
        public Uri insert(Uri uri, ContentValues values) {
            return null;
        }
    }

    @Before
@@ -1384,7 +1395,8 @@ public class DcTrackerTest extends TelephonyTest {
    @SmallTest
    public void testFetchDunApnWhileRoaming() {
        doReturn(true).when(mServiceState).getRoaming();
        mBundle.putBoolean(CarrierConfigManager.KEY_DISABLE_DUN_APN_WHILE_ROAMING, true);
        mBundle.putBoolean(CarrierConfigManager
                .KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, true);

        sendInitializationEvents();

@@ -1393,8 +1405,15 @@ public class DcTrackerTest extends TelephonyTest {

        Settings.Global.putString(mContext.getContentResolver(),
                Settings.Global.TETHER_DUN_APN, dunApnString);

        DcTracker spyDct = spy(mDct);
        doReturn(true).when(spyDct).isPreferredApnUserEdited();
        // Expect non-empty DUN APN list
        assertEquals(1, spyDct.fetchDunApns().size());

        doReturn(false).when(spyDct).isPreferredApnUserEdited();
        // Expect empty DUN APN list
        assertEquals(0, mDct.fetchDunApns().size());
        assertEquals(0, spyDct.fetchDunApns().size());

        Settings.Global.putString(mContext.getContentResolver(),
                Settings.Global.TETHER_DUN_APN, null);