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 Original line Diff line number Diff line
@@ -2111,7 +2111,6 @@ public class DataConnection extends StateMachine {
                String logStr = "Changed from " + mNetworkCapabilities + " to "
                String logStr = "Changed from " + mNetworkCapabilities + " to "
                        + networkCapabilities + ", Data RAT="
                        + networkCapabilities + ", Data RAT="
                        + mPhone.getServiceState().getRilDataRadioTechnology()
                        + mPhone.getServiceState().getRilDataRadioTechnology()
                        + ", DUN APN=\"" + mDct.fetchDunApn() + "\""
                        + ", mApnSetting=" + mApnSetting;
                        + ", mApnSetting=" + mApnSetting;
                mNetCapsLocalLog.log(logStr);
                mNetCapsLocalLog.log(logStr);
                log(logStr);
                log(logStr);
+95 −43
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.internal.telephony.dataconnection;
package com.android.internal.telephony.dataconnection;


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


    /**
    /**
     * Fetch dun apn
     * Fetch the DUN apns
     * @return ApnSetting to be used for dun
     * @return a list of DUN ApnSetting objects
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    public ApnSetting fetchDunApn() {
    public @NonNull ArrayList<ApnSetting> fetchDunApns() {
        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
            log("fetchDunApns: net.tethering.noprovisioning=true ret: empty list");
            return null;
            return new ArrayList<ApnSetting>(0);
        }
        }
        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
        IccRecords r = mIccRecords.get();
        IccRecords r = mIccRecords.get();
        String operator = (r != null) ? r.getOperatorNumeric() : "";
        String operator = (r != null) ? r.getOperatorNumeric() : "";
        ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
        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),
        // 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).
        // APN database, and config_tether_apndata resource (to be deprecated soon).
        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
        if (!TextUtils.isEmpty(apnData)) {
        if (!TextUtils.isEmpty(apnData)) {
            dunCandidates.addAll(ApnSetting.arrayFromString(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
        // 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
                    // apn may be null if apnString isn't valid or has error parsing
                    if (apn != null) dunCandidates.add(apn);
                    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);
                        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 (dunSetting.hasMvnoParams()) {
                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
                    if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
                            dunSetting.mvnoMatchData)) {
                            dunSetting.mvnoMatchData)) {
                        retDunSetting = dunSetting;
                        retDunSettings.add(dunSetting);
                        break;
                    }
                    }
                } else if (mMvnoMatched == false) {
                } else if (mMvnoMatched == false) {
                    retDunSetting = dunSetting;
                    retDunSettings.add(dunSetting);
                    break;
                }
                }
            }
            }
        }
        }


        if (VDBG) log("fetchDunApn: dunSetting=" + retDunSetting);
        if (VDBG) log("fetchDunApns: dunSettings=" + retDunSettings);
        return retDunSetting;
        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() {
    public boolean hasMatchedTetherApnSetting() {
        ApnSetting matched = fetchDunApn();
        ArrayList<ApnSetting> matches = fetchDunApns();
        log("hasMatchedTetherApnSetting: APN=" + matched);
        log("hasMatchedTetherApnSetting: APNs=" + matches);
        return matched != null;
        return matches.size() > 0;
    }
    }


    /**
    /**
@@ -1776,7 +1789,8 @@ public class DcTracker extends Handler {
        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
        if (ServiceState.isCdma(rilRat)) return true;
        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) {
    private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
        String apnType = apnContext.getApnType();
        String apnType = apnContext.getApnType();
        ApnSetting dunSetting = null;
        ArrayList<ApnSetting> dunSettings = null;


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


        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
        if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
            ApnSetting dun = fetchDunApn();
            ArrayList<ApnSetting> dunApns = fetchDunApns();
            if (dun != null) {
            if (dunApns.size() > 0) {
                for (ApnSetting dun : dunApns) {
                    apnList.add(dun);
                    apnList.add(dun);
                    if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
                    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,
                if (ServiceState.bitmaskHasTech(mPreferredApn.networkTypeBitmask,
                        ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
                        ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
                    apnList.add(mPreferredApn);
                    apnList.add(mPreferredApn);
                    apnList = sortApnListByPreferred(apnList);
                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
                    return apnList;
                    return apnList;
                } else {
                } else {
@@ -3515,10 +3536,41 @@ public class DcTracker extends Handler {
        } else {
        } else {
            loge("mAllApnSettings is null!");
            loge("mAllApnSettings is null!");
        }
        }

        apnList = sortApnListByPreferred(apnList);
        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
        if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
        return 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) {
    private String apnListToString (ArrayList<ApnSetting> apns) {
        StringBuilder result = new StringBuilder();
        StringBuilder result = new StringBuilder();
        for (int i = 0, size = apns.size(); i < size; i++) {
        for (int i = 0, size = apns.size(); i < size; i++) {
+26 −14
Original line number Original line Diff line number Diff line
@@ -89,6 +89,7 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.Answer;


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


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


        @Override
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
        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,                      // network_type_bitmask
                            0                       // apn_set_id
                            0                       // apn_set_id
                    });
                    });

                    return mc;
                    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;
            return null;
@@ -392,7 +403,8 @@ public class DcTrackerTest extends TelephonyTest {


        @Override
        @Override
        public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
        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());
        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
    }
    }


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


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


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


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


        ApnSetting dunApnExpected = ApnSetting.fromString(dunApnString1);
        ApnSetting dunApnExpected = ApnSetting.fromString(dunApnString1);


@@ -1326,11 +1337,12 @@ public class DcTrackerTest extends TelephonyTest {
        // set that we prefer apn set 1
        // set that we prefer apn set 1
        ContentValues values = new ContentValues();
        ContentValues values = new ContentValues();
        values.put(Telephony.Carriers.APN_SET_ID, 1);
        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
        // return APN from Setting with apnSetId=1
        ApnSetting dunApn = mDct.fetchDunApn();
        ArrayList<ApnSetting> dunApns = mDct.sortApnListByPreferred(mDct.fetchDunApns());
        assertTrue(dunApnExpected.equals(dunApn));
        assertEquals(2, dunApns.size());
        assertTrue(dunApnExpected.equals(dunApns.get(0)));
    }
    }


    // Test oos
    // Test oos