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

Commit 27408c67 authored by Sarah Chin's avatar Sarah Chin
Browse files

Notify link status changed on connected or disconnected only

NetworkTypeController relies on link status changed events to
distinguish RRC idle vs connected if it does not use physical channel
config indications.
If data is unexpectedly disconnected, DN/DNC might not send the link
status changed event. When a DataNetwork disconnects, update the link
status to make sure we don't miss an INACTIVE state update.
When we receive a data call response in connecting state, the link
status can be prematurely updated. Update the link status only and
defer notifying DNC of the change until the data network is in
connected or disconnected state.
If the data network is already in connected state, update the link
status if it has changed.

Test: atest DataNetworkTest, DataNetworkControllerTest
Test: manual basic data tests
Bug: 279380751
Bug: 276710123
Change-Id: I877b3ed736a0c81b8a0dd692dfdc49a832642ab0
parent 6593a98a
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -1340,13 +1340,14 @@ public class DataNetwork extends StateMachine {
                }
            }

            // If we've ever received PCO data before connected, now it's the time to
            // process it.
            // If we've ever received PCO data before connected, now it's the time to process it.
            mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap())
                    .forEach((pcoId, pcoData) -> {
                        onPcoDataChanged(pcoData);
                    });

            mDataNetworkCallback.invokeFromExecutor(
                    () -> mDataNetworkCallback.onLinkStatusChanged(DataNetwork.this, mLinkStatus));
            notifyPreciseDataConnectionState();
            updateSuspendState();
        }
@@ -1598,6 +1599,9 @@ public class DataNetwork extends StateMachine {
            //************************************************************//

            if (mEverConnected) {
                mLinkStatus = DataCallResponse.LINK_STATUS_INACTIVE;
                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                        .onLinkStatusChanged(DataNetwork.this, mLinkStatus));
                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                        .onDisconnected(DataNetwork.this, mFailCause, mTearDownReason));
                if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
@@ -2302,8 +2306,13 @@ public class DataNetwork extends StateMachine {
        if (mLinkStatus != response.getLinkStatus()) {
            mLinkStatus = response.getLinkStatus();
            log("Link status updated to " + DataUtils.linkStatusToString(mLinkStatus));
            mDataNetworkCallback.invokeFromExecutor(
                    () -> mDataNetworkCallback.onLinkStatusChanged(DataNetwork.this, mLinkStatus));
            if (isConnected()) {
                // If the data network is in a transition state, the link status will be notified
                // upon entering connected or disconnected state. If the data network is already
                // connected, send the updated link status from the updated data call response.
                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                        .onLinkStatusChanged(DataNetwork.this, mLinkStatus));
            }
        }

        // Set link addresses
+10 −1
Original line number Diff line number Diff line
@@ -1299,6 +1299,8 @@ public class DataNetworkControllerTest extends TelephonyTest {
        verifyAllDataDisconnected();
        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
                eq(DataCallResponse.LINK_STATUS_INACTIVE));
    }

    @Test
@@ -1461,7 +1463,8 @@ public class DataNetworkControllerTest extends TelephonyTest {
        verifyAllDataDisconnected();
        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();

        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
                eq(DataCallResponse.LINK_STATUS_INACTIVE));

        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
        // Now RAT changes from GSM to UMTS
@@ -2335,6 +2338,8 @@ public class DataNetworkControllerTest extends TelephonyTest {

        // Verify all data disconnected.
        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
                eq(DataCallResponse.LINK_STATUS_INACTIVE));

        // A new data network should be connected on IWLAN
        List<DataNetwork> dataNetworkList = getDataNetworks();
@@ -2395,6 +2400,8 @@ public class DataNetworkControllerTest extends TelephonyTest {

        // Verify all data disconnected.
        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
                eq(DataCallResponse.LINK_STATUS_INACTIVE));

        // Should setup a new one instead of handover.
        verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
@@ -4243,6 +4250,8 @@ public class DataNetworkControllerTest extends TelephonyTest {
        verifyAllDataDisconnected();
        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
                eq(DataCallResponse.LINK_STATUS_INACTIVE));
    }

    @Test
+62 −24
Original line number Diff line number Diff line
@@ -202,11 +202,24 @@ public class DataNetworkTest extends TelephonyTest {
        doAnswer(invocation -> {
            final Message msg = (Message) invocation.getArguments()[10];

            DataCallResponse response = new DataCallResponse.Builder()
            DataCallResponse response = createDataCallResponse(
                    cid, DataCallResponse.LINK_STATUS_ACTIVE, tds);
            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));
    }

    private DataCallResponse createDataCallResponse(int cid, int linkStatus,
            List<TrafficDescriptor> tds) {
        return new DataCallResponse.Builder()
                .setCause(0)
                .setRetryDurationMillis(-1L)
                .setId(cid)
                    .setLinkStatus(2)
                .setLinkStatus(linkStatus)
                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
                .setInterfaceName("ifname")
                .setAddresses(Arrays.asList(
@@ -226,13 +239,6 @@ public class DataNetworkTest extends TelephonyTest {
                .setQosBearerSessions(new ArrayList<>())
                .setTrafficDescriptors(tds)
                .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));
    }

    private void setFailedSetupDataResponse(DataServiceManager dsm,
@@ -1769,4 +1775,36 @@ public class DataNetworkTest extends TelephonyTest {
        assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
                InetAddresses.parseNumericAddress(IPV4_ADDRESS));
    }

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

        // verify link status sent on connected
        verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT));
        verify(mDataNetworkCallback).onLinkStatusChanged(eq(mDataNetworkUT),
                eq(DataCallResponse.LINK_STATUS_ACTIVE));

        // data state updated
        DataCallResponse response = createDataCallResponse(123,
                DataCallResponse.LINK_STATUS_DORMANT, Collections.emptyList());
        mDataNetworkUT.sendMessage(8 /*EVENT_DATA_STATE_CHANGED*/, new AsyncResult(
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, List.of(response), null));
        processAllMessages();

        // verify link status sent on data state updated
        assertThat(mDataNetworkUT.isConnected()).isTrue();
        verify(mDataNetworkCallback).onLinkStatusChanged(eq(mDataNetworkUT),
                eq(DataCallResponse.LINK_STATUS_DORMANT));

        // RIL crash
        mDataNetworkUT.sendMessage(4 /*EVENT_RADIO_NOT_AVAILABLE*/);
        processAllMessages();

        // verify link status sent on disconnected
        verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT),
                eq(DataFailCause.RADIO_NOT_AVAILABLE), eq(DataNetwork.TEAR_DOWN_REASON_NONE));
        verify(mDataNetworkCallback).onLinkStatusChanged(eq(mDataNetworkUT),
                eq(DataCallResponse.LINK_STATUS_INACTIVE));
    }
}