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

Commit dc7e2cc5 authored by Jack Yu's avatar Jack Yu Committed by Automerger Merge Worker
Browse files

Switch data profile when handover am: 9cb80b29

parents c951b396 9cb80b29
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ public class DataEvaluation {
        RETRY_AFTER_DISCONNECTED,
        /** Data setup retry. */
        DATA_RETRY,
        /** Handover between IWLAN and cellular. */
        /** For handover evaluation, or for network tearing down after handover succeeds/fails. */
        DATA_HANDOVER,
        /** Preferred transport changed. */
        PREFERRED_TRANSPORT_CHANGED,
+32 −5
Original line number Diff line number Diff line
@@ -542,7 +542,13 @@ public class DataNetwork extends StateMachine {
    private @Nullable KeepaliveTracker mKeepaliveTracker;

    /** The data profile used to establish this data network. */
    private final @NonNull DataProfile mDataProfile;
    private @NonNull DataProfile mDataProfile;

    /**
     * The data profile used for data handover. Some carriers might use different data profile
     * between IWLAN and cellular. Only set before handover started.
     */
    private @Nullable DataProfile mHandoverDataProfile;

    /** The network capabilities of this data network. */
    private @NonNull NetworkCapabilities mNetworkCapabilities;
@@ -2872,17 +2878,35 @@ public class DataNetwork extends StateMachine {
        // state in framework, we should set this flag to true as well so the modem will not reject
        // the data call setup (because the modem actually thinks the device is roaming).
        boolean allowRoaming = mPhone.getDataRoamingEnabled()
                || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()
                /*|| isUnmeteredUseOnly()*/));
                || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()));

        mHandoverDataProfile = mDataProfile;
        int targetNetworkType = getDataNetworkType(targetTransport);
        if (targetNetworkType != TelephonyManager.NETWORK_TYPE_UNKNOWN
                && !mAttachedNetworkRequestList.isEmpty()) {
            TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0);
            DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
                    .getDataProfileForNetworkRequest(networkRequest, targetNetworkType);
            // Some carriers have different profiles between cellular and IWLAN. We need to
            // dynamically switch profile, but only when those profiles have same APN name.
            if (dataProfile != null && dataProfile.getApnSetting() != null
                    && mDataProfile.getApnSetting() != null
                    && TextUtils.equals(dataProfile.getApnSetting().getApnName(),
                    mDataProfile.getApnSetting().getApnName())
                    && !dataProfile.equals(mDataProfile)) {
                mHandoverDataProfile = dataProfile;
                log("Used different data profile for handover. " + mDataProfile);
            }
        }

        logl("Start handover from " + AccessNetworkConstants.transportTypeToString(mTransport)
                + " to " + AccessNetworkConstants.transportTypeToString(targetTransport));
        // Send the handover request to the target transport data service.
        mDataServiceManagers.get(targetTransport).setupDataCall(
                DataUtils.networkTypeToAccessNetworkType(getDataNetworkType(targetTransport)),
                mDataProfile, isModemRoaming, allowRoaming,
                mHandoverDataProfile, isModemRoaming, allowRoaming,
                DataService.REQUEST_REASON_HANDOVER, mLinkProperties, mPduSessionId,
                mNetworkSliceInfo, mDataProfile.getTrafficDescriptor(), true,
                mNetworkSliceInfo, mHandoverDataProfile.getTrafficDescriptor(), true,
                obtainMessage(EVENT_HANDOVER_RESPONSE, retryEntry));
        transitionTo(mHandoverState);
    }
@@ -2911,6 +2935,9 @@ public class DataNetwork extends StateMachine {
            // Update the logging tag
            mLogTag = "DN-" + mInitialNetworkAgentId + "-"
                    + ((mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) ? "C" : "I");
            // Switch the data profile. This is no-op in most of the case since almost all carriers
            // use same data profile between IWLAN and cellular.
            mDataProfile = mHandoverDataProfile;
            updateDataNetwork(response);
            if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                // Handover from WWAN to WLAN
+10 −0
Original line number Diff line number Diff line
@@ -2700,6 +2700,11 @@ public class DataNetworkController extends Handler {
        // manager.
        sendMessage(obtainMessage(EVENT_EVALUATE_PREFERRED_TRANSPORT,
                dataNetwork.getApnTypeNetworkCapability(), 0));

        // There might be network we didn't tear down in the last evaluation due to handover in
        // progress. We should evaluate again.
        sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
                DataEvaluationReason.DATA_HANDOVER));
    }

    /**
@@ -2720,6 +2725,11 @@ public class DataNetworkController extends Handler {
        logl("Handover failed. " + dataNetwork + ", cause=" + DataFailCause.toString(cause)
                + ", retryDelayMillis=" + retryDelayMillis + "ms, handoverFailureMode="
                + DataCallResponse.failureModeToString(handoverFailureMode));
        // There might be network we didn't tear down in the last evaluation due to handover in
        // progress. We should evaluate again.
        sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
                DataEvaluationReason.DATA_HANDOVER));

        if (dataNetwork.getAttachedNetworkRequestList().isEmpty()) {
            log("onDataNetworkHandoverFailed: No network requests attached to " + dataNetwork
                    + ". No need to retry since the network will be torn down soon.");
+104 −19
Original line number Diff line number Diff line
@@ -189,7 +189,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
            .setPreferred(false)
            .build();

    private final DataProfile mImsDataProfile = new DataProfile.Builder()
    private final DataProfile mImsCellularDataProfile = new DataProfile.Builder()
            .setApnSetting(new ApnSetting.Builder()
                    .setId(2164)
                    .setOperatorNumeric("12345")
@@ -202,7 +202,6 @@ public class DataNetworkControllerTest extends TelephonyTest {
                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
                    .setCarrierEnabled(true)
                    .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                            | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN
                            | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT))
                    .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                            | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN
@@ -216,6 +215,27 @@ public class DataNetworkControllerTest extends TelephonyTest {
            .setPreferred(false)
            .build();

    private final DataProfile mImsIwlanDataProfile = new DataProfile.Builder()
            .setApnSetting(new ApnSetting.Builder()
                    .setId(2164)
                    .setOperatorNumeric("12345")
                    .setEntryName("ims_apn")
                    .setApnName("ims_apn")
                    .setUser("user")
                    .setPassword("passwd")
                    .setApnTypeBitmask(ApnSetting.TYPE_IMS)
                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
                    .setRoamingProtocol(ApnSetting.PROTOCOL_IPV6)
                    .setCarrierEnabled(true)
                    .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN))
                    .setProfileId(1235)
                    .setMaxConns(321)
                    .setWaitTime(456)
                    .setMaxConnsTime(789)
                    .build())
            .setPreferred(false)
            .build();

    private final DataProfile mEmergencyDataProfile = new DataProfile.Builder()
            .setApnSetting(new ApnSetting.Builder()
                    .setEntryName("DEFAULT EIMS")
@@ -363,6 +383,10 @@ public class DataNetworkControllerTest extends TelephonyTest {
    }

    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid) {
        setSuccessfulSetupDataResponse(dsm, cid, 0L);
    }

    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid, long delay) {
        doAnswer(invocation -> {
            final Message msg = (Message) invocation.getArguments()[10];

@@ -378,11 +402,15 @@ public class DataNetworkControllerTest extends TelephonyTest {
            mDataCallResponses.get(transport).put(cid, response);
            msg.getData().putParcelable("data_call_response", response);
            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
            msg.sendToTarget();
            msg.getTarget().sendMessageDelayed(msg, delay);

            mDataCallListChangedRegistrants.get(transport).notifyRegistrants(
                    new AsyncResult(transport, new ArrayList<>(mDataCallResponses.get(
                            transport).values()), null));
            final int t = transport;
            msg.getTarget().postDelayed(() -> {
                mDataCallListChangedRegistrants.get(t).notifyRegistrants(
                        new AsyncResult(t, new ArrayList<>(mDataCallResponses.get(
                                t).values()), null));

            }, delay + 100);
            return null;
        }).when(dsm).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
                anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
@@ -661,8 +689,10 @@ public class DataNetworkControllerTest extends TelephonyTest {
            TelephonyNetworkRequest networkRequest =
                    (TelephonyNetworkRequest) invocation.getArguments()[0];
            int networkType = (int) invocation.getArguments()[1];
            List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile, mImsDataProfile,
                    mEmergencyDataProfile, mFotaDataProfile, mTetheringDataProfile);
            List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile,
                    mImsCellularDataProfile,
                    mImsIwlanDataProfile, mEmergencyDataProfile, mFotaDataProfile,
                    mTetheringDataProfile);
            for (DataProfile dataProfile : profiles) {
                if (dataProfile.canSatisfy(networkRequest.getCapabilities())
                        && (dataProfile.getApnSetting().getNetworkTypeBitmask() == 0
@@ -917,7 +947,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        processAllMessages();
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
                NetworkCapabilities.NET_CAPABILITY_MMTEL);
        verifyConnectedNetworkHasDataProfile(mImsDataProfile);
        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);
        List<DataNetwork> dataNetworkList = getDataNetworks();
        assertThat(dataNetworkList.get(0).getLinkProperties().getAddresses()).containsExactly(
                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
@@ -1636,13 +1666,20 @@ public class DataNetworkControllerTest extends TelephonyTest {
    @Test
    public void testHandoverDataNetwork() throws Exception {
        testSetupImsDataNetwork();

        DataNetwork dataNetwork = getDataNetworks().get(0);
        // Before handover the data profile is the cellular IMS data profile
        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);

        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);

        DataNetwork dataNetwork = getDataNetworks().get(0);
        // Verify that IWLAN handover succeeded.
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);

        // After handover the data profile is the IWLAN IMS data profile
        verifyConnectedNetworkHasDataProfile(mImsIwlanDataProfile);
    }

    @Test
@@ -1745,7 +1782,10 @@ public class DataNetworkControllerTest extends TelephonyTest {
        processAllMessages();

        // Bring up IMS PDN on IWLAN
        testSetupImsDataNetwork();
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
        processAllMessages();
        verifyConnectedNetworkHasDataProfile(mImsIwlanDataProfile);

        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1836,11 +1876,9 @@ public class DataNetworkControllerTest extends TelephonyTest {

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

        DataNetwork dataNetwork = getDataNetworks().get(0);
@@ -1890,6 +1928,48 @@ public class DataNetworkControllerTest extends TelephonyTest {

    }

    // Test the device enters from 4G to 3G, and QNS switches the pref just before that happens.
    // Make sure we don't tear down the network and let it handover to IWLAN successfully.
    @Test
    public void testHandoverDataNetworkWhileSwitchTo3G() throws Exception {
        testSetupImsDataNetwork();

        DataNetwork dataNetwork = getDataNetworks().get(0);
        // Before handover the data profile is the cellular IMS data profile
        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);

        // Long delay handover
        setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 1, 3000);
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
        mAccessNetworksManagerCallback.onPreferredTransportChanged(
                NetworkCapabilities.NET_CAPABILITY_IMS);
        serviceStateChanged(TelephonyManager.NETWORK_TYPE_UMTS,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
        processAllMessages();

        // Move the time a little bit, handover still not responded.
        moveTimeForward(500);
        processAllMessages();
        dataNetwork = getDataNetworks().get(0);
        // Verify the network is still on cellular, waiting for handover, although already on 3G.
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);

        // Now handover should complete.
        moveTimeForward(5000);
        processAllMessages();

        dataNetwork = getDataNetworks().get(0);
        // Verify that IWLAN handover succeeded.
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);

        // After handover the data profile is the IWLAN IMS data profile
        verifyConnectedNetworkHasDataProfile(mImsIwlanDataProfile);
    }


    @Test
    public void testSetupDataNetworkRetrySuggestedByNetwork() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
@@ -2033,7 +2113,7 @@ public class DataNetworkControllerTest extends TelephonyTest {

        // TAC changes should clear the already-scheduled retry and throttling.
        assertThat(mDataNetworkControllerUT.getDataRetryManager().isAnySetupRetryScheduled(
                mImsDataProfile, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isFalse();
                mImsCellularDataProfile, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isFalse();

        // But DNC should re-evaluate unsatisfied request and setup IMS again.
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
@@ -2200,7 +2280,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
                NetworkCapabilities.NET_CAPABILITY_MMTEL);
        verifyConnectedNetworkHasDataProfile(mImsDataProfile);
        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);
        List<DataNetwork> dataNetworks = getDataNetworks();
        assertThat(dataNetworks).hasSize(1);
        dataNetworks.get(0).tearDown(DataNetwork.TEAR_DOWN_REASON_RAT_NOT_ALLOWED);
@@ -2209,7 +2289,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        // Make sure IMS network is still connected.
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
                NetworkCapabilities.NET_CAPABILITY_MMTEL);
        verifyConnectedNetworkHasDataProfile(mImsDataProfile);
        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);

        // Now connectivity service requests to tear down the data network.
        mDataNetworkControllerUT.removeNetworkRequest(networkRequest);
@@ -2569,7 +2649,12 @@ public class DataNetworkControllerTest extends TelephonyTest {
        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
        processAllMessages();

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

        // Change the preference to cellular
        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,