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

Commit 877810fc authored by Jack Yu's avatar Jack Yu Committed by Android (Google) Code Review
Browse files

Merge "Delayed IMS tear down when voice call is ongoing" into tm-dev

parents af3d911f c4fc0d07
Loading
Loading
Loading
Loading
+11 −5
Original line number Original line Diff line number Diff line
@@ -2248,11 +2248,7 @@ public class DataNetwork extends StateMachine {


    private void onTearDown(@TearDownReason int reason) {
    private void onTearDown(@TearDownReason int reason) {
        logl("onTearDown: reason=" + tearDownReasonToString(reason));
        logl("onTearDown: reason=" + tearDownReasonToString(reason));
        if (mDataConfigManager.isImsDelayTearDownEnabled()
        if (shouldDelayTearDown()) {
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && reason == TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState() != PhoneConstants.State.IDLE) {
            logl("onTearDown: Delay IMS tear down until call ends.");
            logl("onTearDown: Delay IMS tear down until call ends.");
            return;
            return;
        }
        }
@@ -2265,6 +2261,16 @@ public class DataNetwork extends StateMachine {
        mInvokedDataDeactivation = true;
        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
     * 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,
     * {@link DisconnectingState} immediately and waiting for condition met. When condition is met,
+17 −5
Original line number Original line Diff line number Diff line
@@ -856,6 +856,22 @@ public class DataNetworkController extends Handler {
                    public void onDataNetworkHandoverRetryStopped(
                    public void onDataNetworkHandoverRetryStopped(
                            @NonNull DataNetwork dataNetwork) {
                            @NonNull DataNetwork dataNetwork) {
                        Objects.requireNonNull(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,
                        tearDownGracefully(dataNetwork,
                                DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED);
                                DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED);
                    }
                    }
@@ -1545,11 +1561,7 @@ public class DataNetworkController extends Handler {
        }
        }


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


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


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


    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, DataCallResponse response) {
    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, DataCallResponse response) {
@@ -506,6 +509,11 @@ public class DataNetworkControllerTest extends TelephonyTest {
                                + "5000|10000|15000|20000|40000|60000|120000|240000|"
                                + "5000|10000|15000|20000|40000|60000|120000|240000|"
                                + "600000|1200000|1800000, maximum_retries=20"
                                + "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.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 1234);


        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL,
        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL,
@@ -1603,10 +1611,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
    @Test
    public void testSetupDataNetworkRetrySuggestedByNetwork() {
    public void testSetupDataNetworkRetrySuggestedByNetwork() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
        mDataNetworkControllerUT.addNetworkRequest(
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllFutureMessages();
        processAllFutureMessages();
@@ -1622,7 +1717,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        mDataNetworkControllerUT.getDataRetryManager()
        mDataNetworkControllerUT.getDataRetryManager()
                .registerCallback(mMockedDataRetryManagerCallback);
                .registerCallback(mMockedDataRetryManagerCallback);
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
        mDataNetworkControllerUT.addNetworkRequest(
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllMessages();
        processAllMessages();
@@ -1671,7 +1766,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
    @Test
    @Test
    public void testSetupDataNetworkPermanentFailure() {
    public void testSetupDataNetworkPermanentFailure() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
        mDataNetworkControllerUT.addNetworkRequest(
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllFutureMessages();
        processAllFutureMessages();
@@ -1686,7 +1781,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
    @Test
    @Test
    public void testSetupDataNetworkNetworkSuggestedNeverRetry() {
    public void testSetupDataNetworkNetworkSuggestedNeverRetry() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
                Long.MAX_VALUE);
                Long.MAX_VALUE, false);
        mDataNetworkControllerUT.addNetworkRequest(
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllFutureMessages();
        processAllFutureMessages();
@@ -1704,7 +1799,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .registerCallback(mMockedDataRetryManagerCallback);
                .registerCallback(mMockedDataRetryManagerCallback);


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

}
}