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

Commit 7a4666cb authored by Jack Yu's avatar Jack Yu Committed by android-build-merger
Browse files

Merge "Fixed that VT dropped when handover from LTE to IWLAN"

am: 5506cb5d

Change-Id: Ica3104d7df9dde0bef4cec63d4b6eeeca3eeec19
parents 3c5f1948 5506cb5d
Loading
Loading
Loading
Loading
+113 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.text.TextUtils;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
@@ -33,6 +34,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

/**
 * This class represents a apn setting for create PDP link
@@ -42,6 +44,7 @@ public class ApnSetting {
    static final String LOG_TAG = "ApnSetting";

    private static final boolean DBG = false;
    private static final boolean VDBG = false;

    static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*";
    static final String V3_FORMAT_REGEX = "^\\[ApnSettingV3\\]\\s*";
@@ -544,6 +547,116 @@ public class ApnSetting {
                && mvnoMatchData.equals(other.mvnoMatchData);
    }

    /**
     * Compare two APN settings
     *
     * Note: This method does not compare 'id', 'bearer', 'bearerBitmask'. We only use this for
     * determining if tearing a data call is needed when conditions change. See
     * cleanUpConnectionsOnUpdatedApns in DcTracker.
     *
     * @param o the other object to compare
     * @param isDataRoaming True if the device is on data roaming
     * @return True if the two APN settings are same
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public boolean equals(Object o, boolean isDataRoaming) {
        if (!(o instanceof ApnSetting)) {
            return false;
        }

        ApnSetting other = (ApnSetting) o;

        return carrier.equals(other.carrier)
                && numeric.equals(other.numeric)
                && apn.equals(other.apn)
                && proxy.equals(other.proxy)
                && mmsc.equals(other.mmsc)
                && mmsProxy.equals(other.mmsProxy)
                && TextUtils.equals(mmsPort, other.mmsPort)
                && port.equals(other.port)
                && TextUtils.equals(user, other.user)
                && TextUtils.equals(password, other.password)
                && authType == other.authType
                && Arrays.deepEquals(types, other.types)
                && typesBitmap == other.typesBitmap
                && (isDataRoaming || protocol.equals(other.protocol))
                && (!isDataRoaming || roamingProtocol.equals(other.roamingProtocol))
                && carrierEnabled == other.carrierEnabled
                && profileId == other.profileId
                && modemCognitive == other.modemCognitive
                && maxConns == other.maxConns
                && waitTime == other.waitTime
                && maxConnsTime == other.maxConnsTime
                && mtu == other.mtu
                && mvnoType.equals(other.mvnoType)
                && mvnoMatchData.equals(other.mvnoMatchData);
    }

    /**
     * Check if neither mention DUN and are substantially similar
     *
     * @param other The other APN settings to compare
     * @return True if two APN settings are similar
     */
    public boolean similar(ApnSetting other) {
        return (!this.canHandleType(PhoneConstants.APN_TYPE_DUN)
                && !other.canHandleType(PhoneConstants.APN_TYPE_DUN)
                && Objects.equals(this.apn, other.apn)
                && !typeSameAny(this, other)
                && xorEquals(this.proxy, other.proxy)
                && xorEquals(this.port, other.port)
                && xorEquals(this.protocol, other.protocol)
                && xorEquals(this.roamingProtocol, other.roamingProtocol)
                && this.carrierEnabled == other.carrierEnabled
                && this.bearerBitmask == other.bearerBitmask
                && this.profileId == other.profileId
                && Objects.equals(this.mvnoType, other.mvnoType)
                && Objects.equals(this.mvnoMatchData, other.mvnoMatchData)
                && xorEquals(this.mmsc, other.mmsc)
                && xorEquals(this.mmsProxy, other.mmsProxy)
                && xorEquals(this.mmsPort, other.mmsPort));
    }

    // check whether the types of two APN same (even only one type of each APN is same)
    private boolean typeSameAny(ApnSetting first, ApnSetting second) {
        if (VDBG) {
            StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
            for (int index1 = 0; index1 < first.types.length; index1++) {
                apnType1.append(first.types[index1]);
                apnType1.append(",");
            }

            StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
            for (int index1 = 0; index1 < second.types.length; index1++) {
                apnType2.append(second.types[index1]);
                apnType2.append(",");
            }
            Rlog.d(LOG_TAG, "APN1: is " + apnType1);
            Rlog.d(LOG_TAG, "APN2: is " + apnType2);
        }

        for (int index1 = 0; index1 < first.types.length; index1++) {
            for (int index2 = 0; index2 < second.types.length; index2++) {
                if (first.types[index1].equals(PhoneConstants.APN_TYPE_ALL)
                        || second.types[index2].equals(PhoneConstants.APN_TYPE_ALL)
                        || first.types[index1].equals(second.types[index2])) {
                    if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return true");
                    return true;
                }
            }
        }

        if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return false");
        return false;
    }

    // equal or one is not specified
    private boolean xorEquals(String first, String second) {
        return (Objects.equals(first, second)
                || TextUtils.isEmpty(first)
                || TextUtils.isEmpty(second));
    }

    // Helper function to convert APN string into a 32-bit bitmask.
    private static int getApnBitmask(String apn) {
        switch (apn) {
+22 −63
Original line number Diff line number Diff line
@@ -101,7 +101,6 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -3379,7 +3378,7 @@ public class DcTracker extends Handler {
            int j = i + 1;
            while (j < mAllApnSettings.size()) {
                second = mAllApnSettings.get(j);
                if (apnsSimilar(first, second)) {
                if (first.similar(second)) {
                    ApnSetting newApn = mergeApns(first, second);
                    mAllApnSettings.set(i, newApn);
                    first = newApn;
@@ -3392,66 +3391,6 @@ public class DcTracker extends Handler {
        }
    }

    //check whether the types of two APN same (even only one type of each APN is same)
    private boolean apnTypeSameAny(ApnSetting first, ApnSetting second) {
        if(VDBG) {
            StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
            for(int index1 = 0; index1 < first.types.length; index1++) {
                apnType1.append(first.types[index1]);
                apnType1.append(",");
            }

            StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
            for(int index1 = 0; index1 < second.types.length; index1++) {
                apnType2.append(second.types[index1]);
                apnType2.append(",");
            }
            log("APN1: is " + apnType1);
            log("APN2: is " + apnType2);
        }

        for(int index1 = 0; index1 < first.types.length; index1++) {
            for(int index2 = 0; index2 < second.types.length; index2++) {
                if(first.types[index1].equals(PhoneConstants.APN_TYPE_ALL) ||
                        second.types[index2].equals(PhoneConstants.APN_TYPE_ALL) ||
                        first.types[index1].equals(second.types[index2])) {
                    if(VDBG)log("apnTypeSameAny: return true");
                    return true;
                }
            }
        }

        if(VDBG)log("apnTypeSameAny: return false");
        return false;
    }

    // Check if neither mention DUN and are substantially similar
    private boolean apnsSimilar(ApnSetting first, ApnSetting second) {
        return (!first.canHandleType(PhoneConstants.APN_TYPE_DUN)
                && !second.canHandleType(PhoneConstants.APN_TYPE_DUN)
                && Objects.equals(first.apn, second.apn)
                && !apnTypeSameAny(first, second)
                && xorEquals(first.proxy, second.proxy)
                && xorEquals(first.port, second.port)
                && xorEquals(first.protocol, second.protocol)
                && xorEquals(first.roamingProtocol, second.roamingProtocol)
                && first.carrierEnabled == second.carrierEnabled
                && first.bearerBitmask == second.bearerBitmask
                && first.profileId == second.profileId
                && Objects.equals(first.mvnoType, second.mvnoType)
                && Objects.equals(first.mvnoMatchData, second.mvnoMatchData)
                && xorEquals(first.mmsc, second.mmsc)
                && xorEquals(first.mmsProxy, second.mmsProxy)
                && xorEquals(first.mmsPort, second.mmsPort));
    }

    // equal or one is not specified
    private boolean xorEquals(String first, String second) {
        return (Objects.equals(first, second) ||
                TextUtils.isEmpty(first) ||
                TextUtils.isEmpty(second));
    }

    private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
        int id = dest.id;
        ArrayList<String> resultTypes = new ArrayList<String>();
@@ -4382,6 +4321,23 @@ public class DcTracker extends Handler {
        }
    }

    private boolean containsAllApns(ArrayList<ApnSetting> oldApnList,
                                    ArrayList<ApnSetting> newApnList) {
        for (ApnSetting newApnSetting : newApnList) {
            boolean canHandle = false;
            for (ApnSetting oldApnSetting : oldApnList) {
                // Make sure at least one of the APN from old list can cover the new APN
                if (oldApnSetting.equals(newApnSetting,
                        mPhone.getServiceState().getDataRoamingFromRegistration())) {
                    canHandle = true;
                    break;
                }
            }
            if (!canHandle) return false;
        }
        return true;
    }

    private void cleanUpConnectionsOnUpdatedApns(boolean tearDown, String reason) {
        if (DBG) log("cleanUpConnectionsOnUpdatedApns: tearDown=" + tearDown);
        if (mAllApnSettings != null && mAllApnSettings.isEmpty()) {
@@ -4401,7 +4357,10 @@ public class DcTracker extends Handler {
                if (VDBG) log("new waitingApns:" + waitingApns);
                if ((currentWaitingApns != null)
                        && ((waitingApns.size() != currentWaitingApns.size())
                        || (!currentWaitingApns.containsAll(waitingApns)))) {
                        // Check if the existing waiting APN list can cover the newly built APN
                        // list. If yes, then we don't need to tear down the existing data call.
                        // TODO: We probably need to rebuild APN list when roaming status changes.
                        || !containsAllApns(currentWaitingApns, waitingApns))) {
                    if (VDBG) log("new waiting apn is different for " + apnContext);
                    apnContext.setWaitingApns(waitingApns);
                    if (!apnContext.isDisconnected()) {
+64 −1
Original line number Diff line number Diff line
@@ -749,4 +749,67 @@ public class ApnSettingTest extends TelephonyTest {
            }
        }
    }

    @Test
    @SmallTest
    public void testEqualsRoamingProtocol() throws Exception {
        ApnSetting apn1 = new ApnSetting(
                1234,
                "310260",
                "",
                "ims",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                -1,
                 new String[]{"ims"},
                "IPV6",
                "",
                true,
                0,
                131071,
                0,
                false,
                0,
                0,
                0,
                1440,
                "",
                "");

        ApnSetting apn2 = new ApnSetting(
                1235,
                "310260",
                "",
                "ims",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                -1,
                new String[]{"ims"},
                "IPV6",
                "IPV6",
                true,
                0,
                131072,
                0,
                false,
                0,
                0,
                0,
                1440,
                "",
                "");

        assertTrue(apn1.equals(apn2, false));
        assertFalse(apn1.equals(apn2, true));
    }
}
 No newline at end of file