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

Commit 2ba5b53a authored by Jack Yu's avatar Jack Yu
Browse files

Supported XCAP on IWLAN if dedicated APN on IWLAN could be found

Supported XCAP on IWLAN if we can find a dedicate APN on IWLAN,
even if the existing cellular network has already supported XCAP.
The logic is same as MMS on IWLAN. When WFC is enabled and an XCAP
on IWLAN data profile could be found, remove the XCAP capability
from the existing data network so a new one on IWLAN can be
established.

Bug: 430266020
Test: Basic telephony functionality tests
Test: Manual
Flag: EXEMPT trivial fix
Change-Id: I265f80a6394174b7cccb716fd46c82c08cf2c3fd
parent a334498c
Loading
Loading
Loading
Loading
+40 −29
Original line number Diff line number Diff line
@@ -472,7 +472,10 @@ public class DataNetwork extends StateMachine {
            NetworkCapabilities.NET_CAPABILITY_MMTEL,
            // Dynamically add and remove MMS capability depending on QNS's preference if there is
            // a transport specific APN alternative.
            NetworkCapabilities.NET_CAPABILITY_MMS
            NetworkCapabilities.NET_CAPABILITY_MMS,
            // Dynamically add and remove XCAP capability depending on QNS's preference if there is
            // a transport specific APN alternative.
            NetworkCapabilities.NET_CAPABILITY_XCAP
    );

    /** The parent state. Any messages not handled by the child state fallback to this. */
@@ -1320,14 +1323,17 @@ public class DataNetwork extends StateMachine {
                        getHandler(), EVENT_VOICE_CALL_ENDED, null);
            }

            if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_MMS)) {
            if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_MMS)
                    || mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
                mAccessNetworksManagerCallback = new AccessNetworksManagerCallback(
                        getHandler()::post) {
                    @Override
                    public void onPreferredTransportChanged(
                            @NetCapability int networkCapability, boolean forceReconnect) {
                        if (networkCapability == NetworkCapabilities.NET_CAPABILITY_MMS) {
                            log("MMS preference changed.");
                        if (networkCapability == NetworkCapabilities.NET_CAPABILITY_MMS
                                || networkCapability == NetworkCapabilities.NET_CAPABILITY_XCAP) {
                            log(DataUtils.networkCapabilityToString(networkCapability)
                                    + " preference changed.");
                            updateNetworkCapabilities();
                        }
                    }
@@ -2565,31 +2571,36 @@ public class DataNetwork extends StateMachine {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

        // Check if the feature force MMS on IWLAN is enabled. When the feature is enabled, MMS
        // will be attempted on IWLAN if possible, even if existing cellular networks already
        // supports IWLAN.
        if (builder.build().hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
            // If QNS sets MMS preferred on IWLAN, and it is possible to setup an MMS network on
            // IWLAN, then we need to remove the MMS capability on the cellular network. This will
            // allow the new MMS network to be brought up on IWLAN when MMS network request arrives.
            if (mAccessNetworksManager.getPreferredTransportByNetworkCapability(
                    NetworkCapabilities.NET_CAPABILITY_MMS)
        // MMS or XCAP will be attempted on IWLAN if possible, even if existing cellular networks
        // already supports IWLAN.
        int[] iwlanPreferredCaps = new int[]{NetworkCapabilities.NET_CAPABILITY_MMS,
                NetworkCapabilities.NET_CAPABILITY_XCAP};
        for (int netCapability : iwlanPreferredCaps) {
            if (builder.build().hasCapability(netCapability)) {
                // If QNS sets MMS/XCAP as preferred on IWLAN, and it is possible to setup an
                // MMS/XCAP network on IWLAN, then we need to remove the MMS capability on the
                // cellular network. This will allow the new MMS/XCAP network to be brought up on
                // IWLAN when MMS/XCAP network request arrives.
                if (mAccessNetworksManager.getPreferredTransportByNetworkCapability(netCapability)
                        == AccessNetworkConstants.TRANSPORT_TYPE_WLAN && mTransport
                        == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {

                    DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
                            .getDataProfileForNetworkRequest(new TelephonyNetworkRequest(
                                            new NetworkRequest.Builder().addCapability(
                                NetworkCapabilities.NET_CAPABILITY_MMS).build(), mPhone, mFlags),
                                                    netCapability).build(), mPhone, mFlags),
                                    TelephonyManager.NETWORK_TYPE_IWLAN, false, false, false);
                // If we find another data data profile that can support MMS on IWLAN, then remove
                // the MMS capability from this cellular network. This will allow IWLAN to be
                // brought up for MMS later.
                if (dataProfile != null && !dataProfile.getApn().equals(mDataProfile.getApn())) {
                    // If we find another data data profile that can support MMS/XCAP on IWLAN, then
                    // remove the MMS/XCAP capability from this cellular network. This will allow
                    // IWLAN to be brought up for MMS/XCAP later.
                    if (dataProfile != null && !dataProfile.getApn()
                            .equals(mDataProfile.getApn())) {
                        log("Found a different apn name " + dataProfile.getApn()
                            + " that can serve MMS on IWLAN. Current data profile "
                            + mDataProfile.getApn());
                    builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
                                + " that can serve "
                                + DataUtils.networkCapabilityToString(netCapability)
                                + " on IWLAN. Current data profile " + mDataProfile.getApn());
                        builder.removeCapability(netCapability);
                    }
                }
            }
        }
+91 −3
Original line number Diff line number Diff line
@@ -133,7 +133,8 @@ public class DataNetworkTest extends TelephonyTest {
            .setApnName("fake_apn")
            .setUser("user")
            .setPassword("passwd")
            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_MMS)
            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_MMS
                    | ApnSetting.TYPE_XCAP)
            .setProtocol(ApnSetting.PROTOCOL_IPV6)
            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
            .setCarrierEnabled(true)
@@ -156,6 +157,18 @@ public class DataNetworkTest extends TelephonyTest {
            .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)
            .build();

    private final ApnSetting mXcapApnSetting = new ApnSetting.Builder()
            .setId(2164)
            .setOperatorNumeric("12345")
            .setEntryName("fake_xcap_apn")
            .setApnName("fake_xcap_apn")
            .setApnTypeBitmask(ApnSetting.TYPE_XCAP)
            .setProtocol(ApnSetting.PROTOCOL_IPV6)
            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
            .setCarrierEnabled(true)
            .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)
            .build();

    private final ApnSetting mImsApnSetting = new ApnSetting.Builder()
            .setId(2163)
            .setOperatorNumeric("12345")
@@ -184,6 +197,11 @@ public class DataNetworkTest extends TelephonyTest {
            .setTrafficDescriptor(new TrafficDescriptor("fake_apn", null))
            .build();

    private final DataProfile mXcapDataProfile = new DataProfile.Builder()
            .setApnSetting(mXcapApnSetting)
            .setTrafficDescriptor(new TrafficDescriptor("fake_apn", null))
            .build();

    private final DataProfile mImsDataProfile = new DataProfile.Builder()
            .setApnSetting(mImsApnSetting)
            .setTrafficDescriptor(new TrafficDescriptor("fake_apn", null))
@@ -2676,8 +2694,8 @@ public class DataNetworkTest extends TelephonyTest {
                .onPreferredTransportChanged(NetworkCapabilities.NET_CAPABILITY_MMS, false);
        processAllMessages();

        // Check if MMS capability is removed, and we don't recreat network agent which triggers
        // powering comsuming internet validation.
        // Check if MMS capability is removed, and we don't recreate network agent which triggers
        // powering consuming internet validation.
        assertThat(mDataNetworkUT.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)).isFalse();
        verify(mockNetworkAgent, never()).abandon();
@@ -2694,6 +2712,76 @@ public class DataNetworkTest extends TelephonyTest {
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)).isTrue();
    }

    @Test
    public void testXcapCapabilityRemovedWhenXcapPreferredOnIwlan() throws Exception {
        setupDataNetwork();

        TelephonyNetworkAgent mockNetworkAgent = Mockito.mock(TelephonyNetworkAgent.class);
        replaceInstance(DataNetwork.class, "mNetworkAgent",
                mDataNetworkUT, mockNetworkAgent);

        assertThat(mDataNetworkUT.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)).isTrue();

        ArgumentCaptor<AccessNetworksManagerCallback> accessNetworksManagerCallbackArgumentCaptor =
                ArgumentCaptor.forClass(AccessNetworksManagerCallback.class);
        verify(mAccessNetworksManager).registerCallback(
                accessNetworksManagerCallbackArgumentCaptor.capture());

        // Now QNS prefers XCAP on IWLAN
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
        // Verify an xcap apn that shares the same apn name doesn't count as an alternative.
        ApnSetting xcapApnWithSameApn = new ApnSetting.Builder()
                .setId(2164)
                .setOperatorNumeric("12345")
                .setEntryName("fake_xcap_apn")
                .setApnName("fake_apn")
                .setApnTypeBitmask(ApnSetting.TYPE_XCAP)
                .setProtocol(ApnSetting.PROTOCOL_IPV6)
                .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
                .setCarrierEnabled(true)
                .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)
                .build();
        doReturn(new DataProfile.Builder().setApnSetting(xcapApnWithSameApn)
                .setTrafficDescriptor(new TrafficDescriptor("fake_apn", null))
                .build()).when(mDataProfileManager).getDataProfileForNetworkRequest(
                any(TelephonyNetworkRequest.class),
                eq(TelephonyManager.NETWORK_TYPE_IWLAN), eq(false), eq(false), eq(false));
        accessNetworksManagerCallbackArgumentCaptor.getValue()
                .onPreferredTransportChanged(NetworkCapabilities.NET_CAPABILITY_XCAP, false);
        processAllMessages();

        // Check if XCAP capability remains intact.
        assertThat(mDataNetworkUT.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)).isTrue();

        // Verify XCAP capability is removed if using a valid XCAP alternative APN.
        doReturn(mXcapDataProfile).when(mDataProfileManager).getDataProfileForNetworkRequest(
                any(TelephonyNetworkRequest.class),
                eq(TelephonyManager.NETWORK_TYPE_IWLAN), eq(false), eq(false), eq(false));
        accessNetworksManagerCallbackArgumentCaptor.getValue()
                .onPreferredTransportChanged(NetworkCapabilities.NET_CAPABILITY_XCAP, false);
        processAllMessages();

        // Check if XCAP capability is removed, and we don't recreate network agent which triggers
        // powering consuming internet validation.
        assertThat(mDataNetworkUT.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)).isFalse();
        verify(mockNetworkAgent, never()).abandon();

        // Now QNS prefers XCAP on WWAN
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
        accessNetworksManagerCallbackArgumentCaptor.getValue()
                .onPreferredTransportChanged(NetworkCapabilities.NET_CAPABILITY_XCAP, false);
        processAllMessages();

        // Check if XCAP capability is added back.
        assertThat(mDataNetworkUT.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)).isTrue();
    }

    @Test
    public void testQosSessionsChanged()  throws Exception {
        createImsDataNetwork(false/*isMmtel*/);