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

Commit 6440e80d authored by Ling Ma's avatar Ling Ma
Browse files

Don't allow similar data profile for setup data call

When setup data call, if a similar data profile(meaning data profiles that only differ by auto-generated id) is already being used by an existing network, don't bring up another network.

Bug: 240090826
Test: atest + data browsing + phone call
Change-Id: Ie216cf30e0aae8c9fcd524187d96b83e6efbf71d
Merged-In: Ie216cf30e0aae8c9fcd524187d96b83e6efbf71d
Merged-In: I13c8619b6543a882dafe28db3eeafcb89da19b38
parent 15cc4653
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -2368,9 +2368,12 @@ public class DataNetworkController extends Handler {
                + dataSetupRetryEntry + ", allowed reason=" + allowedReason + ", service state="
                + mServiceState);
        for (DataNetwork dataNetwork : mDataNetworkList) {
            if (dataNetwork.getDataProfile().equals(dataProfile)) {
            DataProfile currentDataProfile = dataNetwork.getDataProfile();
            if (dataProfile.equals(currentDataProfile)
                    || mDataProfileManager.areDataProfilesSharingApn(
                            dataProfile, currentDataProfile)) {
                log("onSetupDataNetwork: Found existing data network " + dataNetwork
                        + " has the same data profile.");
                        + " using the same or a similar data profile.");
                if (dataSetupRetryEntry != null) {
                    dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
                }
+9 −4
Original line number Diff line number Diff line
@@ -498,7 +498,7 @@ public class DataProfileManager extends Handler {
                    setPreferredDataProfile(preferredDataProfile);
                } else {
                    preferredDataProfile = mAllDataProfiles.stream()
                            .filter(dp -> areDataProfileSharingApn(dp, mPreferredDataProfile))
                            .filter(dp -> areDataProfilesSharingApn(dp, mPreferredDataProfile))
                            .findFirst()
                            .orElse(null);
                    if (preferredDataProfile != null) {
@@ -731,7 +731,7 @@ public class DataProfileManager extends Handler {
     * @return {@code true} if the data profile is essentially the preferred data profile.
     */
    public boolean isDataProfilePreferred(@NonNull DataProfile dataProfile) {
        return areDataProfileSharingApn(dataProfile, mPreferredDataProfile);
        return areDataProfilesSharingApn(dataProfile, mPreferredDataProfile);
    }

    /**
@@ -965,14 +965,19 @@ public class DataProfileManager extends Handler {

        // Only check the APN from the profile is compatible or not.
        return mAllDataProfiles.stream()
                .anyMatch(dp -> areDataProfileSharingApn(dataProfile, dp));
                .filter(dp -> dp.getApnSetting() != null
                        && (dp.getApnSetting().getApnSetId()
                        == Telephony.Carriers.MATCH_ALL_APN_SET_ID
                        || dp.getApnSetting().getApnSetId() == mPreferredDataProfileSetId))
                .anyMatch(dp -> areDataProfilesSharingApn(dataProfile, dp));

    }

    /**
     * @return {@code true} if both data profiles' APN setting are non-null and essentially the same
     * (non-essential elements include e.g.APN Id).
     */
    private boolean areDataProfileSharingApn(@Nullable DataProfile a, @Nullable DataProfile b) {
    public boolean areDataProfilesSharingApn(@Nullable DataProfile a, @Nullable DataProfile b) {
        return a != null
                && b != null
                && a.getApnSetting() != null
+110 −0
Original line number Diff line number Diff line
@@ -194,6 +194,36 @@ public class DataNetworkControllerTest extends TelephonyTest {
            .setPreferred(false)
            .build();

    // The same data profile but with different auto generated ID, should be considered the same as
    // mGeneralPurposeDataProfile
    private final DataProfile mDuplicatedGeneralPurposeDataProfile = new DataProfile.Builder()
            .setApnSetting(new ApnSetting.Builder()
                    .setId(3612)
                    .setOperatorNumeric("12345")
                    .setEntryName("internet_supl_mms_apn")
                    .setApnName("internet_supl_mms_apn")
                    .setUser("user")
                    .setPassword("passwd")
                    .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL
                            | ApnSetting.TYPE_MMS)
                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
                    .setCarrierEnabled(true)
                    .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                            | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN
                            | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT))
                    .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                            | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT
                            | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS
                            | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
                    .setProfileId(1234)
                    .setMaxConns(321)
                    .setWaitTime(456)
                    .setMaxConnsTime(789)
                    .build())
            .setPreferred(false)
            .build();

    private final DataProfile mImsCellularDataProfile = new DataProfile.Builder()
            .setApnSetting(new ApnSetting.Builder()
                    .setId(2164)
@@ -781,6 +811,17 @@ public class DataNetworkControllerTest extends TelephonyTest {
            return null;
        }).when(mDataProfileManager).isDataProfileCompatible(any(DataProfile.class));

        doAnswer(invocation -> {
            DataProfile a = (DataProfile) invocation.getArguments()[0];
            DataProfile b = (DataProfile) invocation.getArguments()[1];
            return a != null
                    && b != null
                    && a.getApnSetting() != null
                    && a.getApnSetting().equals(b.getApnSetting(),
                    mPhone.getServiceState().getDataRoamingFromRegistration());
        }).when(mDataProfileManager).areDataProfilesSharingApn(any(DataProfile.class),
                any(DataProfile.class));

        doAnswer(invocation -> {
            TelephonyNetworkRequest networkRequest =
                    (TelephonyNetworkRequest) invocation.getArguments()[0];
@@ -1032,6 +1073,75 @@ public class DataNetworkControllerTest extends TelephonyTest {
        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkConnected(any());
    }

    @Test
    public void testSetupDataNetworkWithSimilarDataProfile() throws Exception {
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllMessages();
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);

        List<DataNetwork> dataNetworkList = getDataNetworks();
        assertThat(dataNetworkList).hasSize(1);
        DataNetwork dataNetwork = dataNetworkList.get(0);
        assertThat(dataNetworkList.get(0).getLinkProperties().getAddresses()).containsExactly(
                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
                InetAddresses.parseNumericAddress(IPV6_ADDRESS));

        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkConnected(any());

        // database updated/reloaded, causing data profile id change
        List<DataProfile> profiles = List.of(mDuplicatedGeneralPurposeDataProfile);
        doAnswer(invocation -> {
            DataProfile dp = (DataProfile) invocation.getArguments()[0];

            if (dp.getApnSetting() == null) return true;

            for (DataProfile dataProfile : profiles) {
                if (dataProfile.getApnSetting() != null
                        && dataProfile.getApnSetting().equals(dp.getApnSetting(), false)) {
                    return true;
                }
            }
            return null;
        }).when(mDataProfileManager).isDataProfileCompatible(any(DataProfile.class));
        doAnswer(invocation -> {
            TelephonyNetworkRequest networkRequest =
                    (TelephonyNetworkRequest) invocation.getArguments()[0];
            int networkType = (int) invocation.getArguments()[1];

            for (DataProfile dataProfile : profiles) {
                if (dataProfile.canSatisfy(networkRequest.getCapabilities())
                        && (dataProfile.getApnSetting().getNetworkTypeBitmask() == 0
                        || (dataProfile.getApnSetting().getNetworkTypeBitmask()
                        & ServiceState.getBitmaskForTech(networkType)) != 0)) {
                    return dataProfile;
                }
            }
            logd("Cannot find data profile to satisfy " + networkRequest + ", network type="
                    + TelephonyManager.getNetworkTypeName(networkType));
            return null;
        }).when(mDataProfileManager).getDataProfileForNetworkRequest(
                any(TelephonyNetworkRequest.class), anyInt());

        // verify the network still connects
        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkConnected(any());

        // A NOT_VCN_MANAGED request cannot be satisfied by the existing network, but will adopt the
        // same data profile
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET,
                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));

        processAllMessages();

        // verify the network still connects
        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkConnected(any());
        // verify we don't try to setup a separate network for the not_vcn_managed request
        dataNetworkList = getDataNetworks();
        assertThat(dataNetworkList).hasSize(1);
    }

    @Test
    public void testSetupImsDataNetwork() throws Exception {
        mDataNetworkControllerUT.addNetworkRequest(