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

Commit fec1b69a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Allow data setup when oos if voice is registered" into tm-dev am: d83d70bd

parents 5ba5e637 d83d70bd
Loading
Loading
Loading
Loading
+59 −32
Original line number Diff line number Diff line
@@ -1285,21 +1285,37 @@ public class DataNetworkController extends Handler {
    }

    /**
     * @return {@code true} if checking registration state is needed before setup data network.
     * {@code false} indicates regardless in-service or out-of-service, setup data request will
     * be sent down to the data service.
     * @param ss The service state to be checked
     * @param transport The transport is used to determine the data registration state
     *
     * @return {@code true} if data is in service or if voice is in service on legacy CS
     * connections (2G/3G) on the non-DDS. In those cases we attempt to attach PS. We don't try for
     * newer RAT because for those PS attach already occurred.
     */
    private boolean shouldCheckRegistrationState() {
        // Always don't check registration state on non-DDS sub.
        if (mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()) {
            return false;
    private boolean serviceStateAllowsPSAttach(@NonNull ServiceState ss,
            @TransportType int transport) {
        // Use the data registration state from the modem instead of the current data registration
        // state, which can be overridden.
        int nriRegState = getDataRegistrationState(ss, transport);
        if (nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
                || nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) return true;

        // If data is OOS on the non-DDS,
        // attempt to attach PS on 2G/3G if CS connection is available.
        return ss.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
                && mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()
                && isLegacyCs(ss.getVoiceNetworkType());
    }

        // TODO: Expand this method to support more scenarios if needed. On Android 12 or older
        //  Android, auto attach is enabled by default. We dropped that support in Android 13 since
        //  it's for the old 2G network. If there are other scenarios that we need to support
        //  auto-attach, can implement the logic in this method.
        return true;
    /**
     * @param voiceNetworkType The voice network type to be checked.
     * @return {@code true} if the network type is on legacy CS connection.
     */
    private boolean isLegacyCs(@NetworkType int voiceNetworkType) {
        int voiceAccessNetworkType = DataUtils.networkTypeToAccessNetworkType(voiceNetworkType);
        return voiceAccessNetworkType == AccessNetworkType.GERAN
                || voiceAccessNetworkType == AccessNetworkType.UTRAN
                || voiceAccessNetworkType == AccessNetworkType.CDMA2000;
    }

    /**
@@ -1384,10 +1400,7 @@ public class DataNetworkController extends Handler {
            return evaluation;
        }

        int regState = getDataRegistrationState(transport);
        if (shouldCheckRegistrationState()
                && regState != NetworkRegistrationInfo.REGISTRATION_STATE_HOME
                && regState != NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) {
        if (!serviceStateAllowsPSAttach(mServiceState, transport)) {
            evaluation.addDataDisallowedReason(DataDisallowedReason.NOT_IN_SERVICE);
        }

@@ -1548,7 +1561,7 @@ public class DataNetworkController extends Handler {
                    + TelephonyManager.getNetworkTypeName(getDataNetworkType(transport))
                    + ", reg state="
                    + NetworkRegistrationInfo.registrationStateToString(
                    getDataRegistrationState(transport))
                    getDataRegistrationState(mServiceState, transport))
                    + ", " + networkRequest);
        }
        return evaluation;
@@ -3064,27 +3077,39 @@ public class DataNetworkController extends Handler {
    /**
     * Check if needed to re-evaluate the unsatisfied network requests.
     *
     * @param oldNri Previous network registration info.
     * @param newNri Current network registration info.
     * @param oldSS Previous raw service state.
     * @param newSS Current raw service state.
     * @param transport The network transport to be checked.
     * @return {@code true} if needed to re-evaluate the unsatisfied network requests.
     */
    private boolean shouldReevaluateNetworkRequests(@Nullable NetworkRegistrationInfo oldNri,
            @Nullable NetworkRegistrationInfo newNri) {
        if (newNri == null) return false;
        if (newNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
    private boolean shouldReevaluateNetworkRequests(@NonNull ServiceState oldSS,
            @NonNull ServiceState newSS, @TransportType int transport)  {
        NetworkRegistrationInfo oldPsNri = oldSS.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, transport);
        NetworkRegistrationInfo newPsNri = newSS.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, transport);

        if (newPsNri == null) return false;
        if (newPsNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
            // Sometimes devices temporarily lose signal and RAT becomes unknown. We don't setup
            // data in this case.
            return false;
        }

        if (oldNri == null
                || oldNri.getAccessNetworkTechnology() != newNri.getAccessNetworkTechnology()
                || (!oldNri.isInService() && newNri.isInService())) {
        if (oldPsNri == null
                || oldPsNri.getAccessNetworkTechnology() != newPsNri.getAccessNetworkTechnology()
                || (!oldPsNri.isInService() && newPsNri.isInService())) {
            return true;
        }

        DataSpecificRegistrationInfo oldDsri = oldNri.getDataSpecificInfo();
        DataSpecificRegistrationInfo newDsri = newNri.getDataSpecificInfo();
        // If CS connection is back to service on non-DDS, reevaluate for potential PS
        if (!serviceStateAllowsPSAttach(oldSS, transport)
                && serviceStateAllowsPSAttach(newSS, transport)) {
            return true;
        }

        DataSpecificRegistrationInfo oldDsri = oldPsNri.getDataSpecificInfo();
        DataSpecificRegistrationInfo newDsri = newPsNri.getDataSpecificInfo();

        if (oldDsri == null) return false;
        if ((newDsri == null || newDsri.getVopsSupportInfo() == null
@@ -3139,7 +3164,7 @@ public class DataNetworkController extends Handler {
                        evaluateDataNetworks = true;
                    }
                }
                if (shouldReevaluateNetworkRequests(oldNri, newNri)) {
                if (shouldReevaluateNetworkRequests(mServiceState, newServiceState, transport)) {
                    if (!hasMessages(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS)) {
                        sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
                                DataEvaluationReason.DATA_SERVICE_STATE_CHANGED));
@@ -3276,11 +3301,13 @@ public class DataNetworkController extends Handler {
    /**
     * Get data registration state based on transport.
     *
     * @param ss The service state from which to extract the data registration state.
     * @param transport The transport.
     * @return The registration state.
     */
    private @RegistrationState int getDataRegistrationState(@TransportType int transport) {
        NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
    private @RegistrationState int getDataRegistrationState(@NonNull ServiceState ss,
            @TransportType int transport) {
        NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, transport);
        if (nri != null) {
            return nri.getRegistrationState();
+84 −5
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyProtoEnums;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataCallResponse.LinkStatus;
@@ -478,17 +479,31 @@ public class DataNetworkControllerTest extends TelephonyTest {
                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));

        serviceStateChanged(networkType, regState, dsri);
        serviceStateChanged(networkType, regState, regState,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
    }

    private void serviceStateChanged(@NetworkType int networkType,
            @RegistrationState int regState, DataSpecificRegistrationInfo dsri) {
        serviceStateChanged(networkType, regState, regState,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
    }

    private void serviceStateChanged(@NetworkType int networkType,
            @RegistrationState int dataRegState, @RegistrationState int voiceRegState,
            @RegistrationState int iwlanRegState, DataSpecificRegistrationInfo dsri) {
        if (dsri == null) {
            dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                    new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
                            LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
        }

        ServiceState ss = new ServiceState();

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .setAccessNetworkTechnology(networkType)
                .setRegistrationState(regState)
                .setRegistrationState(dataRegState)
                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                .setDataSpecificInfo(dsri)
                .build());
@@ -496,18 +511,20 @@ public class DataNetworkControllerTest extends TelephonyTest {
        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setRegistrationState(iwlanRegState)
                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                .build());

        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .setAccessNetworkTechnology(networkType)
                .setRegistrationState(regState)
                .setRegistrationState(voiceRegState)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        ss.setDataRoamingFromRegistration(regState
        ss.setDataRoamingFromRegistration(dataRegState
                == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
        processServiceStateRegStateForTest(ss);

        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

@@ -515,6 +532,28 @@ public class DataNetworkControllerTest extends TelephonyTest {
        processAllMessages();
    }

    // set SS reg state base on SST impl, where WLAN overrides WWAN's data reg.
    private void processServiceStateRegStateForTest(ServiceState ss) {
        int wlanRegState = ss.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN).getRegistrationState();
        if (wlanRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
            ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
        } else {
            int cellularRegState = ss.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getRegistrationState();
            int dataState = (cellularRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
                    || cellularRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING)
                    ? ServiceState.STATE_IN_SERVICE : ServiceState.STATE_OUT_OF_SERVICE;
            ss.setDataRegState(dataState);
        }
        int voiceRegState = ss.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getRegistrationState();
        int voiceState = (voiceRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
                || voiceRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING)
                ? ServiceState.STATE_IN_SERVICE : ServiceState.STATE_OUT_OF_SERVICE;
        ss.setVoiceRegState(voiceState);
    }

    private void updateTransport(@NetCapability int capability, @TransportType int transport) {
        doReturn(transport).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(capability);
@@ -2778,6 +2817,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        processServiceStateRegStateForTest(ss);
        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

@@ -2827,6 +2867,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        processServiceStateRegStateForTest(ss);
        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

@@ -2885,6 +2926,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        processServiceStateRegStateForTest(ss);
        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

@@ -2948,6 +2990,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        processServiceStateRegStateForTest(ss);
        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

@@ -2994,6 +3037,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                .build());
        processServiceStateRegStateForTest(ss);
        doReturn(ss).when(mSST).getServiceState();
        doReturn(ss).when(mPhone).getServiceState();

@@ -3146,4 +3190,39 @@ public class DataNetworkControllerTest extends TelephonyTest {
        // Data should be torn down on this non-preferred sub.
        verifyAllDataDisconnected();
    }

    @Test
    public void testSetupDataOnNonDds() throws Exception {
        // Now DDS switched to phone 1
        doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
        TelephonyNetworkRequest request = createNetworkRequest(
                NetworkCapabilities.NET_CAPABILITY_MMS);

        // Test Don't allow setup if both data and voice OOS
        serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_1XRTT,
                // data, voice, Iwlan reg state
                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);
        mDataNetworkControllerUT.addNetworkRequest(request);
        processAllMessages();

        verifyAllDataDisconnected();

        // Test Don't allow setup if CS is in service, but current RAT is already PS(e.g. LTE)
        serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_LTE,
                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);

        verifyAllDataDisconnected();

        // Test Allow if voice is in service if RAT is 2g/3g
        serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_1XRTT,
                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
                NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);

        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
    }
}