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

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

Delayed IMS tear down when voice call is ongoing

If delayed IMS tear down carrier config is on, then
we should delay IMS tear down when handover retry stops.

Bug: 228141189
Test: atest DataNetworkControllerTest
Change-Id: I3e6fc857ba750259696f207715ae7abaf8129bef
parent 5d102efd
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -2244,11 +2244,7 @@ public class DataNetwork extends StateMachine {

    private void onTearDown(@TearDownReason int reason) {
        logl("onTearDown: reason=" + tearDownReasonToString(reason));
        if (mDataConfigManager.isImsDelayTearDownEnabled()
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && reason == TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState() != PhoneConstants.State.IDLE) {
        if (shouldDelayTearDown()) {
            logl("onTearDown: Delay IMS tear down until call ends.");
            return;
        }
@@ -2261,6 +2257,16 @@ public class DataNetwork extends StateMachine {
        mInvokedDataDeactivation = true;
    }

    /**
     * @return {@code true} if this tear down should be delayed on this data network.
     */
    public boolean shouldDelayTearDown() {
        return mDataConfigManager.isImsDelayTearDownEnabled()
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState() != PhoneConstants.State.IDLE;
    }

    /**
     * Tear down the data network when condition is met or timed out. Data network will enter
     * {@link DisconnectingState} immediately and waiting for condition met. When condition is met,
+17 −5
Original line number Diff line number Diff line
@@ -842,6 +842,22 @@ public class DataNetworkController extends Handler {
                    public void onDataNetworkHandoverRetryStopped(
                            @NonNull DataNetwork dataNetwork) {
                        Objects.requireNonNull(dataNetwork);
                        int preferredTransport = mAccessNetworksManager
                                .getPreferredTransportByNetworkCapability(
                                        dataNetwork.getApnTypeNetworkCapability());
                        if (dataNetwork.getTransport() == preferredTransport) {
                            log("onDataNetworkHandoverRetryStopped: " + dataNetwork + " is already "
                                    + "on the preferred transport "
                                    + AccessNetworkConstants.transportTypeToString(
                                            preferredTransport));
                            return;
                        }
                        if (dataNetwork.shouldDelayTearDown()) {
                            log("onDataNetworkHandoverRetryStopped: Delay IMS tear down until call "
                                    + "ends. " + dataNetwork);
                            return;
                        }

                        tearDownGracefully(dataNetwork,
                                DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED);
                    }
@@ -1531,11 +1547,7 @@ public class DataNetworkController extends Handler {
        }

        boolean delayImsTearDown = false;
        if (mDataConfigManager.isImsDelayTearDownEnabled()
                && dataNetwork.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState() != PhoneConstants.State.IDLE) {
        if (dataNetwork.shouldDelayTearDown()) {
            // Some carriers requires delay tearing down IMS network until the call ends even if
            // VoPS bit is lost.
            log("Ignore VoPS bit and delay IMS tear down until call ends.");
+104 −10
Original line number Diff line number Diff line
@@ -299,21 +299,24 @@ public class DataNetworkControllerTest extends TelephonyTest {
    }

    private void setFailedSetupDataResponse(DataServiceManager dsm, @DataFailureCause int cause,
            long retryMillis) {
            long retryMillis, boolean forHandover) {
        doAnswer(invocation -> {
            final Message msg = (Message) invocation.getArguments()[10];

            DataCallResponse response = new DataCallResponse.Builder()
                    .setCause(cause)
                    .setRetryDurationMillis(retryMillis)
                    .setHandoverFailureMode(
                            DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER)
                    .build();
            msg.getData().putParcelable("data_call_response", response);
            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
            msg.sendToTarget();
            return null;
        }).when(dsm).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
                anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
                any(Message.class));
                anyBoolean(), forHandover ? eq(DataService.REQUEST_REASON_HANDOVER)
                        : eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(),
                anyBoolean(), any(Message.class));
    }

    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid) {
@@ -468,6 +471,11 @@ public class DataNetworkControllerTest extends TelephonyTest {
                                + "5000|10000|15000|20000|40000|60000|120000|240000|"
                                + "600000|1200000|1800000, maximum_retries=20"
                });
        mCarrierConfig.putStringArray(
                CarrierConfigManager.KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY,
                new String[] {"retry_interval=1000|2000|4000|8000|16000, maximum_retries=5"
                });

        mCarrierConfig.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 1234);

        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL,
@@ -1536,10 +1544,97 @@ public class DataNetworkControllerTest extends TelephonyTest {

    }

    @Test
    public void testHandoverDataNetworkRetry() throws Exception {
        testSetupImsDataNetwork();

        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
                DataFailCause.HANDOVER_FAILED, -1, true);
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
        mAccessNetworksManagerCallback.onPreferredTransportChanged(
                NetworkCapabilities.NET_CAPABILITY_IMS);
        processAllMessages();

        DataNetwork dataNetwork = getDataNetworks().get(0);
        // Verify that data network is still on cellular
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);

        setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 1);

        processAllFutureMessages();

        dataNetwork = getDataNetworks().get(0);
        // Verify that data network is handovered to IWLAN
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
    }

    @Test
    public void testHandoverDataNetworkRetryReachedMaximum() throws Exception {
        testSetupImsDataNetwork();

        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
                DataFailCause.HANDOVER_FAILED, -1, true);
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
        mAccessNetworksManagerCallback.onPreferredTransportChanged(
                NetworkCapabilities.NET_CAPABILITY_IMS);
        processAllFutureMessages();

        // Should retried 5 times, which is the maximum based on the retry config rules.
        verify(mMockedWlanDataServiceManager, times(6)).setupDataCall(anyInt(),
                any(DataProfile.class), anyBoolean(), anyBoolean(),
                eq(DataService.REQUEST_REASON_HANDOVER), any(), anyInt(), any(), any(),
                anyBoolean(), any(Message.class));

        DataNetwork dataNetwork = getDataNetworks().get(0);
        // Verify that data network is finally setup on IWLAN.
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);

        verify(mMockedWlanDataServiceManager).setupDataCall(anyInt(),
                any(DataProfile.class), anyBoolean(), anyBoolean(),
                eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(),
                anyBoolean(), any(Message.class));
    }

    @Test
    public void testHandoverDataNetworkRetryReachedMaximumDelayImsTearDown() throws Exception {
        // Voice call is ongoing
        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();
        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
                true);
        carrierConfigChanged();

        testSetupImsDataNetwork();

        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
                DataFailCause.HANDOVER_FAILED, -1, true);
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
        mAccessNetworksManagerCallback.onPreferredTransportChanged(
                NetworkCapabilities.NET_CAPABILITY_IMS);
        processAllFutureMessages();

        // Should retried 5 times, which is the maximum based on the retry config rules.
        verify(mMockedWlanDataServiceManager, times(6)).setupDataCall(anyInt(),
                any(DataProfile.class), anyBoolean(), anyBoolean(),
                eq(DataService.REQUEST_REASON_HANDOVER), any(), anyInt(), any(), any(),
                anyBoolean(), any(Message.class));

        DataNetwork dataNetwork = getDataNetworks().get(0);
        // Verify that data network is still on WWAN because voice call is still ongoing.
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);

    }

    @Test
    public void testSetupDataNetworkRetrySuggestedByNetwork() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllFutureMessages();
@@ -1555,7 +1650,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        mDataNetworkControllerUT.getDataRetryManager()
                .registerCallback(mMockedDataRetryManagerCallback);
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllMessages();
@@ -1604,7 +1699,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
    @Test
    public void testSetupDataNetworkPermanentFailure() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllFutureMessages();
@@ -1619,7 +1714,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
    @Test
    public void testSetupDataNetworkNetworkSuggestedNeverRetry() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
                Long.MAX_VALUE);
                Long.MAX_VALUE, false);
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllFutureMessages();
@@ -1637,7 +1732,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .registerCallback(mMockedDataRetryManagerCallback);

        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
                10000);
                10000, false);
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
        processAllMessages();
@@ -2078,7 +2173,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
    @Test
    public void testNetworkRequestRemovedBeforeRetry() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
        TelephonyNetworkRequest networkRequest = createNetworkRequest(
                NetworkCapabilities.NET_CAPABILITY_INTERNET);
        mDataNetworkControllerUT.addNetworkRequest(networkRequest);
@@ -2124,5 +2219,4 @@ public class DataNetworkControllerTest extends TelephonyTest {
        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
    }

}