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

Commit 4f57e71c authored by Jordan Liu's avatar Jordan Liu Committed by Gerrit Code Review
Browse files

Merge "DcTracker prioritizes preferred apn set"

parents 29c29857 6d96b8b3
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -2111,7 +2111,6 @@ public class DataConnection extends StateMachine {
                String logStr = "Changed from " + mNetworkCapabilities + " to "
                        + networkCapabilities + ", Data RAT="
                        + mPhone.getServiceState().getRilDataRadioTechnology()
                        + ", DUN APN=\"" + mDct.fetchDunApn() + "\""
                        + ", mApnSetting=" + mApnSetting;
                mNetCapsLocalLog.log(logStr);
                log(logStr);
+95 −43
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.telephony.dataconnection;

import android.annotation.NonNull;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
@@ -1689,27 +1690,27 @@ public class DcTracker extends Handler {
    }

    /**
     * Fetch dun apn
     * @return ApnSetting to be used for dun
     * Fetch the DUN apns
     * @return a list of DUN ApnSetting objects
     */
    @VisibleForTesting
    public ApnSetting fetchDunApn() {
    public @NonNull ArrayList<ApnSetting> fetchDunApns() {
        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
            return null;
            log("fetchDunApns: net.tethering.noprovisioning=true ret: empty list");
            return new ArrayList<ApnSetting>(0);
        }
        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
        IccRecords r = mIccRecords.get();
        String operator = (r != null) ? r.getOperatorNumeric() : "";
        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
        ApnSetting retDunSetting = null;
        ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();

        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
        // APN database, and config_tether_apndata resource (to be deprecated soon).
        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
        if (!TextUtils.isEmpty(apnData)) {
            dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
            if (VDBG) log("fetchDunApn: dunCandidates from Setting: " + dunCandidates);
            if (VDBG) log("fetchDunApns: dunCandidates from Setting: " + dunCandidates);
        }

        // todo: remove this and config_tether_apndata after APNs are moved from overlay to apns xml
@@ -1724,7 +1725,7 @@ public class DcTracker extends Handler {
                    // apn may be null if apnString isn't valid or has error parsing
                    if (apn != null) dunCandidates.add(apn);
                }
                if (VDBG) log("fetchDunApn: dunCandidates from resource: " + dunCandidates);
                if (VDBG) log("fetchDunApns: dunCandidates from resource: " + dunCandidates);
            }
        }

@@ -1735,7 +1736,7 @@ public class DcTracker extends Handler {
                        dunCandidates.add(apn);
                    }
                }
                if (VDBG) log("fetchDunApn: dunCandidates from database: " + dunCandidates);
                if (VDBG) log("fetchDunApns: dunCandidates from database: " + dunCandidates);
            }
        }

@@ -1748,24 +1749,36 @@ public class DcTracker extends Handler {
                if (dunSetting.hasMvnoParams()) {
                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
                            dunSetting.mvnoMatchData)) {
                        retDunSetting = dunSetting;
                        break;
                        retDunSettings.add(dunSetting);
                    }
                } else if (mMvnoMatched == false) {
                    retDunSetting = dunSetting;
                    break;
                    retDunSettings.add(dunSetting);
                }
            }
        }

        if (VDBG) log("fetchDunApn: dunSetting=" + retDunSetting);
        return retDunSetting;
        if (VDBG) log("fetchDunApns: dunSettings=" + retDunSettings);
        return retDunSettings;
    }

    private int getPreferredApnSetId() {
        Cursor c = mPhone.getContext().getContentResolver()
                .query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI,
                    "preferapnset/subId/" + mPhone.getSubId()),
                        new String[] {Telephony.Carriers.APN_SET_ID}, null, null, null);
        if (c.getCount() < 1) {
            loge("getPreferredApnSetId: no APNs found");
            return Telephony.Carriers.NO_SET_SET;
        } else {
            c.moveToFirst();
            return c.getInt(0 /* index of Telephony.Carriers.APN_SET_ID */);
        }
    }

    public boolean hasMatchedTetherApnSetting() {
        ApnSetting matched = fetchDunApn();
        log("hasMatchedTetherApnSetting: APN=" + matched);
        return matched != null;
        ArrayList<ApnSetting> matches = fetchDunApns();
        log("hasMatchedTetherApnSetting: APNs=" + matches);
        return matches.size() > 0;
    }

    /**
@@ -1776,7 +1789,8 @@ public class DcTracker extends Handler {
        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
        if (ServiceState.isCdma(rilRat)) return true;

        return (fetchDunApn() != null);
        ArrayList<ApnSetting> apns = fetchDunApns();
        return apns.size() > 0;
    }

    /**
@@ -2449,10 +2463,10 @@ public class DcTracker extends Handler {

    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
        String apnType = apnContext.getApnType();
        ApnSetting dunSetting = null;
        ArrayList<ApnSetting> dunSettings = null;

        if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
            dunSetting = fetchDunApn();
            dunSettings = sortApnListByPreferred(fetchDunApns());
        }
        if (DBG) {
            log("checkForCompatibleConnectedApnContext: apnContext=" + apnContext );
@@ -2465,7 +2479,8 @@ public class DcTracker extends Handler {
            if (curDcac != null) {
                ApnSetting apnSetting = curApnCtx.getApnSetting();
                log("apnSetting: " + apnSetting);
                if (dunSetting != null) {
                if (dunSettings != null && dunSettings.size() > 0) {
                    for (ApnSetting dunSetting : dunSettings) {
                        if (dunSetting.equals(apnSetting)) {
                            switch (curApnCtx.getState()) {
                                case CONNECTED:
@@ -2479,11 +2494,13 @@ public class DcTracker extends Handler {
                                case CONNECTING:
                                    potentialDcac = curDcac;
                                    potentialApnCtx = curApnCtx;
                                    break;
                                default:
                                    // Not connected, potential unchanged
                                    break;
                            }
                        }
                    }
                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
                    switch (curApnCtx.getState()) {
                        case CONNECTED:
@@ -2497,6 +2514,7 @@ public class DcTracker extends Handler {
                        case CONNECTING:
                            potentialDcac = curDcac;
                            potentialApnCtx = curApnCtx;
                            break;
                        default:
                            // Not connected, potential unchanged
                            break;
@@ -3434,11 +3452,13 @@ public class DcTracker extends Handler {
        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();

        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
            ApnSetting dun = fetchDunApn();
            if (dun != null) {
            ArrayList<ApnSetting> dunApns = fetchDunApns();
            if (dunApns.size() > 0) {
                for (ApnSetting dun : dunApns) {
                    apnList.add(dun);
                    if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
                return apnList;
                }
                return sortApnListByPreferred(apnList);
            }
        }

@@ -3479,6 +3499,7 @@ public class DcTracker extends Handler {
                if (ServiceState.bitmaskHasTech(mPreferredApn.networkTypeBitmask,
                        ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
                    apnList.add(mPreferredApn);
                    apnList = sortApnListByPreferred(apnList);
                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
                    return apnList;
                } else {
@@ -3515,10 +3536,41 @@ public class DcTracker extends Handler {
        } else {
            loge("mAllApnSettings is null!");
        }

        apnList = sortApnListByPreferred(apnList);
        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
        return apnList;
    }

    /**
     * Sort a list of ApnSetting objects, with the preferred APNs at the front of the list
     *
     * e.g. if the preferred APN set = 2 and we have
     *   1. APN with apn_set_id = 0 = Carriers.NO_SET_SET (no set is set)
     *   2. APN with apn_set_id = 1 (not preferred set)
     *   3. APN with apn_set_id = 2 (preferred set)
     * Then the return order should be (3, 1, 2) or (3, 2, 1)
     *
     * e.g. if the preferred APN set = Carriers.NO_SET_SET (no preferred set) then the
     * return order can be anything
     */
    @VisibleForTesting
    public ArrayList<ApnSetting> sortApnListByPreferred(ArrayList<ApnSetting> list) {
        if (list == null || list.size() <= 1) return list;
        int preferredApnSetId = getPreferredApnSetId();
        if (preferredApnSetId != Telephony.Carriers.NO_SET_SET) {
            list.sort(new Comparator<ApnSetting>() {
                @Override
                public int compare(ApnSetting apn1, ApnSetting apn2) {
                    if (apn1.apnSetId == preferredApnSetId) return -1;
                    if (apn2.apnSetId == preferredApnSetId) return 1;
                    return 0;
                }
            });
        }
        return list;
    }

    private String apnListToString (ArrayList<ApnSetting> apns) {
        StringBuilder result = new StringBuilder();
        for (int i = 0, size = apns.size(); i < size; i++) {
+26 −14
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
@@ -182,6 +183,7 @@ public class DcTrackerTest extends TelephonyTest {
    }

    private class ApnSettingContentProvider extends MockContentProvider {
        private int mPreferredApnSet = 0;

        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
@@ -383,8 +385,17 @@ public class DcTrackerTest extends TelephonyTest {
                            0,                      // network_type_bitmask
                            0                       // apn_set_id
                    });

                    return mc;
                }
            } else if (uri.isPathPrefixMatch(
                    Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "preferapnset"))) {
                MatrixCursor mc = new MatrixCursor(
                        new String[]{Telephony.Carriers.APN_SET_ID});
                // apn_set_id is the only field used with this URL
                mc.addRow(new Object[]{ mPreferredApnSet });
                mc.addRow(new Object[]{ 0 });
                return mc;
            }

            return null;
@@ -392,7 +403,8 @@ public class DcTrackerTest extends TelephonyTest {

        @Override
        public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
            return 0;
            mPreferredApnSet = values.getAsInteger(Telephony.Carriers.APN_SET_ID);
            return 1;
        }
    }

@@ -1276,7 +1288,7 @@ public class DcTrackerTest extends TelephonyTest {
        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
    }

    // Test for fetchDunApn()
    // Test for fetchDunApns()
    @Test
    @SmallTest
    public void testFetchDunApn() {
@@ -1291,20 +1303,19 @@ public class DcTrackerTest extends TelephonyTest {
        Settings.Global.putString(mContext.getContentResolver(),
                Settings.Global.TETHER_DUN_APN, dunApnString);
        // should return APN from Setting
        ApnSetting dunApn = mDct.fetchDunApn();
        ApnSetting dunApn = mDct.fetchDunApns().get(0);
        assertTrue(dunApnExpected.equals(dunApn));

        Settings.Global.putString(mContext.getContentResolver(),
                Settings.Global.TETHER_DUN_APN, null);
        // should return APN from db
        dunApn = mDct.fetchDunApn();
        dunApn = mDct.fetchDunApns().get(0);
        assertEquals(FAKE_APN5, dunApn.apn);
    }

    // Test for fetchDunApn() with apn set id
    // Test for fetchDunApns() with apn set id
    @Test
    @SmallTest
    @Ignore
    public void testFetchDunApnWithPreferredApnSet() {
        logd("Sending EVENT_RECORDS_LOADED");
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
@@ -1312,10 +1323,10 @@ public class DcTrackerTest extends TelephonyTest {

        // apnSetId=1
        String dunApnString1 = "[ApnSettingV5]HOT mobile PC,pc.hotm,,,,,,,,,440,10,,DUN,,,true,"
                + "0,,,,,,,,,1";
        // apnSetId=2
        String dunApnString2 = "[ApnSettingV5]HOT mobile PC,pc.hotm,,,,,,,,,440,10,,DUN,,,true,"
                + "0,,,,,,,,,2";
                + "0,,,,,,,,,,1";
        // apnSetId=0
        String dunApnString2 = "[ApnSettingV5]HOT mobile PC,pc.coldm,,,,,,,,,440,10,,DUN,,,true,"
                + "0,,,,,,,,,,0";

        ApnSetting dunApnExpected = ApnSetting.fromString(dunApnString1);

@@ -1326,11 +1337,12 @@ public class DcTrackerTest extends TelephonyTest {
        // set that we prefer apn set 1
        ContentValues values = new ContentValues();
        values.put(Telephony.Carriers.APN_SET_ID, 1);
        cr.update(PREFERAPN_URI, values, null, null); // currently a noop
        cr.update(PREFERAPN_URI, values, null, null);

        // TODO(70172263) should return APN from Setting with apnSetId=1
        ApnSetting dunApn = mDct.fetchDunApn();
        assertTrue(dunApnExpected.equals(dunApn));
        // return APN from Setting with apnSetId=1
        ArrayList<ApnSetting> dunApns = mDct.sortApnListByPreferred(mDct.fetchDunApns());
        assertEquals(2, dunApns.size());
        assertTrue(dunApnExpected.equals(dunApns.get(0)));
    }

    // Test oos