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

Commit a7ab4c7d authored by Jack Yu's avatar Jack Yu
Browse files

Do not dynamically change MMTEL capability

This CL partially reverted ag/17922489, which dynamically changes
MMTEL capability. If the network request contains MMTEL, but telephony
remove it, connectivity service will consider the request can't be
satisfied anymore. So it will initiate tear down. So we should not
remove MMTEL once it's reported as the network's capability. So the
behavior becomes

1. If the network request contains only IMS, but not MMTEL, moving
   between VoPS and non-VoPS will not cause any IMS PDN tear down.
2. If the network request contains both IMS and MMTEL, when the
   device moves from VoPS to non-VoPS, telephony will
   1. When voice call is ongoing, telephony will NOT tear down the
      IMS PDN if delay IMS tear down carrier config is turned on.
   2. When voice call is not ongoing, telephony will initiate
      graceful IMS tear down, and let IMS service has chance to
      perform IMS de-registration.

Fix: 233912777
Test: Basic testing + atest DataNetworkControllerTest DataNetworkTest
Merged-In: Ie51c319ea26fd54f1a0846e1c3cb228481a67230
Change-Id: Ie51c319ea26fd54f1a0846e1c3cb228481a67230
parent 66f7536e
Loading
Loading
Loading
Loading
+5 −10
Original line number Original line Diff line number Diff line
@@ -1314,8 +1314,6 @@ public class DataNetwork extends StateMachine {
                case EVENT_VOICE_CALL_STARTED:
                case EVENT_VOICE_CALL_STARTED:
                case EVENT_VOICE_CALL_ENDED:
                case EVENT_VOICE_CALL_ENDED:
                case EVENT_CSS_INDICATOR_CHANGED:
                case EVENT_CSS_INDICATOR_CHANGED:
                    // We might entered non-VoPS network. Need to update the network capability to
                    // remove MMTEL capability.
                    updateSuspendState();
                    updateSuspendState();
                    updateNetworkCapabilities();
                    updateNetworkCapabilities();
                    break;
                    break;
@@ -1493,8 +1491,6 @@ public class DataNetwork extends StateMachine {
                case EVENT_CSS_INDICATOR_CHANGED:
                case EVENT_CSS_INDICATOR_CHANGED:
                case EVENT_VOICE_CALL_STARTED:
                case EVENT_VOICE_CALL_STARTED:
                case EVENT_VOICE_CALL_ENDED:
                case EVENT_VOICE_CALL_ENDED:
                    // We might entered non-VoPS network. Need to update the network capability to
                    // remove MMTEL capability.
                    updateSuspendState();
                    updateSuspendState();
                    updateNetworkCapabilities();
                    updateNetworkCapabilities();
                    break;
                    break;
@@ -1828,14 +1824,13 @@ public class DataNetwork extends StateMachine {
            }
            }
        }
        }


        // If voice call is on-going, do not change MMTEL capability, which is an immutable
        // Once we set the MMTEL capability, we should never remove it because it's an immutable
        // capability. Changing it will result in CS tearing down IMS network, and the voice
        // capability defined by connectivity service. When the device enters from VoPS to non-VoPS,
        // call will drop.
        // we should perform grace tear down from data network controller if needed.
        if (shouldDelayImsTearDown() && mNetworkCapabilities != null
        if (mNetworkCapabilities != null
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
            // Previous capability has MMTEL, so add it again.
            // Previous capability has MMTEL, so add it again.
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
            log("Delayed IMS tear down. Reporting MMTEL capability for now.");
        } else {
        } else {
            // Always add MMTEL capability on IMS network unless network explicitly indicates VoPS
            // Always add MMTEL capability on IMS network unless network explicitly indicates VoPS
            // not supported.
            // not supported.
@@ -2491,7 +2486,7 @@ public class DataNetwork extends StateMachine {
    public boolean shouldDelayImsTearDown() {
    public boolean shouldDelayImsTearDown() {
        return mDataConfigManager.isImsDelayTearDownEnabled()
        return mDataConfigManager.isImsDelayTearDownEnabled()
                && mNetworkCapabilities != null
                && mNetworkCapabilities != null
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState()
                && mPhone.getImsPhone().getCallTracker().getState()
                != PhoneConstants.State.IDLE;
                != PhoneConstants.State.IDLE;
+25 −0
Original line number Original line Diff line number Diff line
@@ -1658,6 +1658,31 @@ public class DataNetworkController extends Handler {
            }
            }
        }
        }


        // If the data network is IMS that supports voice call, and has MMTEL request (client
        // specified VoPS is required.)
        if (dataNetwork.getAttachedNetworkRequestList().get(
                new int[]{NetworkCapabilities.NET_CAPABILITY_MMTEL}) != null) {
            // When reaching here, it means the network supports MMTEL, and also has MMTEL request
            // attached to it.
            if (!dataNetwork.shouldDelayImsTearDown()) {
                if (dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                    NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
                            NetworkRegistrationInfo.DOMAIN_PS,
                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
                    if (nri != null) {
                        DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
                        if (dsri != null && dsri.getVopsSupportInfo() != null
                                && !dsri.getVopsSupportInfo().isVopsSupported()) {
                            evaluation.addDataDisallowedReason(
                                    DataDisallowedReason.VOPS_NOT_SUPPORTED);
                        }
                    }
                }
            } else {
                log("Ignored VoPS check due to delay IMS tear down until call ends.");
            }
        }

        // Check if data is disabled
        // Check if data is disabled
        boolean dataDisabled = false;
        boolean dataDisabled = false;
        if (!mDataSettingsManager.isDataEnabled()) {
        if (!mDataSettingsManager.isDataEnabled()) {
+128 −2
Original line number Original line Diff line number Diff line
@@ -2830,7 +2830,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
        processAllMessages();
        processAllMessages();


        // Even though the network request deos not have MMTEL, but the network support it, so
        // Even though the network request does not have MMTEL, but the network support it, so
        // the network capabilities should still have MMTEL.
        // the network capabilities should still have MMTEL.
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
                NetworkCapabilities.NET_CAPABILITY_MMTEL);
                NetworkCapabilities.NET_CAPABILITY_MMTEL);
@@ -2844,11 +2844,137 @@ public class DataNetworkControllerTest extends TelephonyTest {
                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
                any(), any(), anyBoolean(), any(Message.class));
                any(), any(), anyBoolean(), any(Message.class));


        // The IMS network should only have IMS, but no MMTEL.
        // The IMS network should still have IMS and MMTEL.
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS);
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS);
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMTEL);
    }

    @Test
    public void testMmtelImsDataNetworkMovingToNonVops() throws Exception {
        ServiceState ss = new ServiceState();

        // VoPS network
        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                .setDataSpecificInfo(dsri)
                .build());

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                .build());

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);

        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
        processAllMessages();

        // Bring up the IMS network that does require MMTEL
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
        processAllMessages();

        // the network capabilities should have IMS and MMTEL.
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
                NetworkCapabilities.NET_CAPABILITY_MMTEL);

        ss = new ServiceState();
        // Non VoPS network
        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                .setDataSpecificInfo(dsri)
                .build());

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                .build());

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
        processAllMessages();

        // The IMS network should be torn down by data network controller.
        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
    }
    }


    @Test
    public void testVoPStoNonVoPSDelayImsTearDown() throws Exception {
        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
                true);
        carrierConfigChanged();

        // VoPS supported
        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);

        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
        processAllMessages();
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS);

        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();

        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);

        // Make sure IMS is still connected.
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
                NetworkCapabilities.NET_CAPABILITY_MMTEL);

        // Call ends
        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
        mDataNetworkControllerUT.obtainMessage(18/*EVENT_VOICE_CALL_ENDED*/).sendToTarget();
        processAllMessages();

        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
    }

    @Test
    @Test
    public void testDeactivateDataOnOldHal() throws Exception {
    public void testDeactivateDataOnOldHal() throws Exception {
        doAnswer(invocation -> {
        doAnswer(invocation -> {
+1 −36
Original line number Original line Diff line number Diff line
@@ -1248,46 +1248,11 @@ public class DataNetworkTest extends TelephonyTest {
        logd("Trigger non VoPS");
        logd("Trigger non VoPS");
        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
        // MMTEL should not be removed.
                NetworkCapabilities.NET_CAPABILITY_MMTEL)).isFalse();
    }

    @Test
    public void testMovingToNonVopsVoiceCallOngoing() throws Exception {
        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
        testCreateImsDataNetwork();

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

        // Voice call ongoing.
        doReturn(PhoneConstants.State.OFFHOOK).when(mImsCT).getState();

        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);

        // Should not lose MMTEL since voice call is ongoing
        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_MMTEL)).isTrue();

        // Voice call ended.
        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
        mDataNetworkUT.sendMessage(23/*EVENT_VOICE_CALL_ENDED*/);
        processAllMessages();

        // MMTEL should be removed.
        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_MMTEL)).isFalse();
    }
    }



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