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

Commit aedf23aa authored by Ling Ma's avatar Ling Ma Committed by Android (Google) Code Review
Browse files

Merge "Allow bring up MMTEL network in non-vope area if configured" into main

parents a46c701c 1b184be0
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -13,3 +13,10 @@ flag {
  description: "Relax handover tear down if the device is currently in voice call."
  bug: "270895912"
}

flag {
  name: "allow_mmtel_in_non_vops"
  namespace: "telephony"
  description: "Allow bring up MMTEL in nonVops area specified by carrier config."
  bug: "241198464"
}
+39 −5
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
@@ -46,6 +47,7 @@ import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataNetworkController.HandoverRule;
import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryRule;
import com.android.internal.telephony.data.DataRetryManager.DataSetupRetryRule;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
@@ -259,6 +261,7 @@ public class DataConfigManager extends Handler {
    private @NonNull final Phone mPhone;
    private @NonNull final String mLogTag;

    @NonNull private final FeatureFlags mFeatureFlags;
    private @NonNull final CarrierConfigManager mCarrierConfigManager;
    private @NonNull PersistableBundle mCarrierConfig = null;
    private @NonNull Resources mResources = null;
@@ -295,6 +298,9 @@ public class DataConfigManager extends Handler {
    private @NonNull final List<HandoverRule> mHandoverRuleList = new ArrayList<>();
    /** {@code True} keep IMS network in case of moving to non VOPS area; {@code false} otherwise.*/
    private boolean mShouldKeepNetworkUpInNonVops = false;
    /** The set of network types that enable VOPS even in non VOPS area. */
    @NonNull private final @CarrierConfigManager.Ims.NetworkType List<Integer>
            mEnabledVopsNetworkTypesInNonVops = new ArrayList<>();
    /**
     * A map of network types to the estimated downlink values by signal strength 0 - 4 for that
     * network type
@@ -309,9 +315,11 @@ public class DataConfigManager extends Handler {
     * @param looper The looper to be used by the handler. Currently the handler thread is the
     * phone process's main thread.
     */
    public DataConfigManager(@NonNull Phone phone, @NonNull Looper looper) {
    public DataConfigManager(@NonNull Phone phone, @NonNull Looper looper,
            @NonNull FeatureFlags featureFlags) {
        super(looper);
        mPhone = phone;
        mFeatureFlags = featureFlags;
        mLogTag = "DCM-" + mPhone.getPhoneId();
        log("DataConfigManager created.");

@@ -666,6 +674,11 @@ public class DataConfigManager extends Handler {
        synchronized (this) {
            mShouldKeepNetworkUpInNonVops = mCarrierConfig.getBoolean(CarrierConfigManager
                    .Ims.KEY_KEEP_PDN_UP_IN_NO_VOPS_BOOL);
            int[] allowedNetworkTypes = mCarrierConfig.getIntArray(
                    CarrierConfigManager.Ims.KEY_IMS_PDN_ENABLED_IN_NO_VOPS_SUPPORT_INT_ARRAY);
            if (allowedNetworkTypes != null) {
                Arrays.stream(allowedNetworkTypes).forEach(mEnabledVopsNetworkTypesInNonVops::add);
            }
        }
    }

@@ -684,9 +697,29 @@ public class DataConfigManager extends Handler {
        return Collections.unmodifiableSet(mCapabilitiesExemptFromSingleDataList);
    }

    /** {@code True} keep IMS network in case of moving to non VOPS area; {@code false} otherwise.*/
    public boolean shouldKeepNetworkUpInNonVops() {
        return mShouldKeepNetworkUpInNonVops;
    /**
     * @param regState The modem reported data registration state.
     * @return {@code true} if should keep IMS network in case of moving to non VOPS area.
     */
    public boolean shouldKeepNetworkUpInNonVops(@NetworkRegistrationInfo.RegistrationState
            int regState) {
        return mShouldKeepNetworkUpInNonVops || allowBringUpNetworkInNonVops(regState);
    }

    /**
     * @param regState The modem reported data registration state.
     * @return {@code true} if allow bring up IMS network in case of moving to non VOPS area.
     */
    public boolean allowBringUpNetworkInNonVops(@NetworkRegistrationInfo.RegistrationState
            int regState) {
        if (!mFeatureFlags.allowMmtelInNonVops()) return false;
        int networkType = -1;
        if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
            networkType = CarrierConfigManager.Ims.NETWORK_TYPE_HOME;
        } else if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) {
            networkType = CarrierConfigManager.Ims.NETWORK_TYPE_ROAMING;
        }
        return mEnabledVopsNetworkTypesInNonVops.contains(networkType);
    }

    /** {@code True} requires ping test to pass on the target slot before switching to it.*/
@@ -1423,7 +1456,8 @@ public class DataConfigManager extends Handler {
        pw.println("Capabilities exempt from single PDN=" + mCapabilitiesExemptFromSingleDataList
                .stream().map(DataUtils::networkCapabilityToString)
                .collect(Collectors.joining(",")));
        pw.println("mShouldKeepNetworkUpInNoVops=" + mShouldKeepNetworkUpInNonVops);
        pw.println("mShouldKeepNetworkUpInNonVops=" + mShouldKeepNetworkUpInNonVops);
        pw.println("mEnabledVopsNetworkTypesInNonVops=" + mEnabledVopsNetworkTypesInNonVops);
        pw.println("isPingTestBeforeAutoDataSwitchRequired="
                + isPingTestBeforeAutoDataSwitchRequired());
        pw.println("Unmetered network types=" + String.join(",", mUnmeteredNetworkTypes));
+32 −23
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ import com.android.internal.telephony.data.DataRetryManager.DataRetryEntry;
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.metrics.DataCallSessionStats;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.util.ArrayUtils;
@@ -440,9 +441,9 @@ public class DataNetwork extends StateMachine {
            // Connectivity service will support NOT_METERED as a mutable and requestable
            // capability.
            NetworkCapabilities.NET_CAPABILITY_NOT_METERED,
            // Even though MMTEL is an immutable capability, we still make it an mutable capability
            // here before we have a better solution to deal with network transition from VoPS
            // to non-VoPS network.
            // Dynamically add and remove MMTEL capability when network transition between VoPS
            // and non-VoPS network if the request is not MMTEL. For MMTEL, we retain the capability
            // to prevent immediate tear down.
            NetworkCapabilities.NET_CAPABILITY_MMTEL
    );

@@ -490,6 +491,9 @@ public class DataNetwork extends StateMachine {
    /** The phone instance. */
    private final @NonNull Phone mPhone;

    /** Feature flags */
    private final @NonNull FeatureFlags mFlags;

    /**
     * The subscription id. This is assigned when the network is created, and not supposed to
     * change afterwards.
@@ -897,7 +901,7 @@ public class DataNetwork extends StateMachine {
     * @param dataAllowedReason The reason that why setting up this data network is allowed.
     * @param callback The callback to receives data network state update.
     */
    public DataNetwork(@NonNull Phone phone, @NonNull Looper looper,
    public DataNetwork(@NonNull Phone phone, FeatureFlags featureFlags, @NonNull Looper looper,
            @NonNull SparseArray<DataServiceManager> dataServiceManagers,
            @NonNull DataProfile dataProfile,
            @NonNull NetworkRequestList networkRequestList,
@@ -911,6 +915,7 @@ public class DataNetwork extends StateMachine {
        initializeStateMachine();

        mPhone = phone;
        mFlags = featureFlags;
        mSubId = phone.getSubId();
        mRil = mPhone.mCi;
        mLinkProperties = new LinkProperties();
@@ -2141,17 +2146,16 @@ public class DataNetwork extends StateMachine {
            }
        }

        // Once we set the MMTEL capability, we should never remove it because it's an immutable
        // If MMTEL capability is requested, we should not remove it because it's an immutable
        // capability defined by connectivity service. When the device enters from VoPS to non-VoPS,
        // we should perform grace tear down from data network controller if needed.
        if (mNetworkCapabilities != null
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
            // Previous capability has MMTEL, so add it again.
        if (hasNetworkCapabilityInNetworkRequests(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
            // Request has MMTEL, add it again so the network won't be unwanted by connectivity.
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
        } else {
        } else if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS)) {
            // Request has IMS capability only.
            // Always add MMTEL capability on IMS network unless network explicitly indicates VoPS
            // not supported.
            if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS)) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
            if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                NetworkRegistrationInfo nri = getNetworkRegistrationInfo();
@@ -2160,14 +2164,19 @@ public class DataNetwork extends StateMachine {
                    // Check if the network is non-VoPS.
                    if (dsri != null && dsri.getVopsSupportInfo() != null
                            && !dsri.getVopsSupportInfo().isVopsSupported()
                                && !mDataConfigManager.shouldKeepNetworkUpInNonVops()) {
                            // Reflect the actual MMTEL if flag on.
                            && (mFlags.allowMmtelInNonVops()
                            // Deceive Connectivity service to satisfy an MMTEL request, this should
                            // be useless because we reach here if no MMTEL request, then removing
                            // MMTEL capability shouldn't have any impacts.
                            || !mDataConfigManager.shouldKeepNetworkUpInNonVops(
                                    nri.getNetworkRegistrationState()))) {
                        builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
                    }
                    log("updateNetworkCapabilities: dsri=" + dsri);
                }
            }
        }
        }

        // Extract network capabilities from the traffic descriptor.
        for (TrafficDescriptor trafficDescriptor : mTrafficDescriptors) {
@@ -2721,7 +2730,7 @@ public class DataNetwork extends StateMachine {
    public boolean shouldDelayImsTearDownDueToInCall() {
        return mDataConfigManager.isImsDelayTearDownUntilVoiceCallEndEnabled()
                && mNetworkCapabilities != null
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState()
                != PhoneConstants.State.IDLE;
+18 −8
Original line number Diff line number Diff line
@@ -813,7 +813,7 @@ public class DataNetworkController extends Handler {
            mDataServiceManagers.put(transport, new DataServiceManager(mPhone, looper, transport));
        }

        mDataConfigManager = new DataConfigManager(mPhone, looper);
        mDataConfigManager = new DataConfigManager(mPhone, looper, featureFlags);

        // ========== Anomaly counters ==========
        mImsThrottleCounter = new SlidingWindowEventCounter(
@@ -1529,7 +1529,9 @@ public class DataNetworkController extends Handler {
            if (nri != null) {
                DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
                if (dsri != null && dsri.getVopsSupportInfo() != null
                        && !dsri.getVopsSupportInfo().isVopsSupported()) {
                        && !dsri.getVopsSupportInfo().isVopsSupported()
                        && !mDataConfigManager.allowBringUpNetworkInNonVops(
                                nri.getNetworkRegistrationState())) {
                    evaluation.addDataDisallowedReason(DataDisallowedReason.VOPS_NOT_SUPPORTED);
                }
            }
@@ -1791,6 +1793,8 @@ public class DataNetworkController extends Handler {
            }
        }

        // It's recommended for IMS service not requesting MMTEL capability, so that MMTEL
        // capability is dynamically added when moving between vops and nonvops area.
        boolean vopsIsRequired = dataNetwork.hasNetworkCapabilityInNetworkRequests(
                NetworkCapabilities.NET_CAPABILITY_MMTEL);

@@ -1813,7 +1817,8 @@ public class DataNetworkController extends Handler {
                        DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
                        if (dsri != null && dsri.getVopsSupportInfo() != null
                                && !dsri.getVopsSupportInfo().isVopsSupported()
                                && !mDataConfigManager.shouldKeepNetworkUpInNonVops()) {
                                && !mDataConfigManager.shouldKeepNetworkUpInNonVops(
                                        nri.getNetworkRegistrationState())) {
                            evaluation.addDataDisallowedReason(
                                    DataDisallowedReason.VOPS_NOT_SUPPORTED);
                        }
@@ -1993,6 +1998,8 @@ public class DataNetworkController extends Handler {
                }

                // Check if VoPS is required, but the target transport is non-VoPS.
                // It's recommended for IMS service not requesting MMTEL capability, so that MMTEL
                // capability is dynamically added when moving between vops and nonvops area.
                NetworkRequestList networkRequestList =
                        dataNetwork.getAttachedNetworkRequestList();
                if (networkRequestList.stream().anyMatch(request
@@ -2001,7 +2008,8 @@ public class DataNetworkController extends Handler {
                    // Check if the network is non-VoPS.
                    if (dsri != null && dsri.getVopsSupportInfo() != null
                            && !dsri.getVopsSupportInfo().isVopsSupported()
                            && !mDataConfigManager.shouldKeepNetworkUpInNonVops()) {
                            && !mDataConfigManager.shouldKeepNetworkUpInNonVops(
                                    nri.getNetworkRegistrationState())) {
                        dataEvaluation.addDataDisallowedReason(
                                DataDisallowedReason.VOPS_NOT_SUPPORTED);
                    }
@@ -2545,8 +2553,8 @@ public class DataNetworkController extends Handler {
                + AccessNetworkConstants.transportTypeToString(transport) + " with " + dataProfile
                + ", and attaching " + networkRequestList.size() + " network requests to it.");

        mDataNetworkList.add(new DataNetwork(mPhone, getLooper(), mDataServiceManagers,
                dataProfile, networkRequestList, transport, allowedReason,
        mDataNetworkList.add(new DataNetwork(mPhone, mFeatureFlags, getLooper(),
                mDataServiceManagers, dataProfile, networkRequestList, transport, allowedReason,
                new DataNetworkCallback(this::post) {
                    @Override
                    public void onSetupDataFailed(@NonNull DataNetwork dataNetwork,
@@ -3390,7 +3398,8 @@ public class DataNetworkController extends Handler {
        }

        if (oldNri.getAccessNetworkTechnology() != newNri.getAccessNetworkTechnology()
                || (!oldNri.isRoaming() && newNri.isRoaming())) {
                // Some CarrierConfig disallows vops in nonVops area for specified home/roaming.
                || (oldNri.isRoaming() != newNri.isRoaming())) {
            return true;
        }

@@ -3440,7 +3449,8 @@ public class DataNetworkController extends Handler {
        if (oldPsNri == null
                || oldPsNri.getAccessNetworkTechnology() != newPsNri.getAccessNetworkTechnology()
                || (!oldPsNri.isInService() && newPsNri.isInService())
                || (oldPsNri.isRoaming() && !newPsNri.isRoaming())) {
                // Some CarrierConfig allows vops in nonVops area for specified home/roaming.
                || (oldPsNri.isRoaming() != newPsNri.isRoaming())) {
            return true;
        }

+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ public class DataConfigManagerTest extends TelephonyTest {
        super.setUp(getClass().getSimpleName());
        mBundle = mContextFixture.getCarrierConfigBundle();
        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
        mDataConfigManagerUT = new DataConfigManager(mPhone, Looper.myLooper());
        mDataConfigManagerUT = new DataConfigManager(mPhone, Looper.myLooper(), mFeatureFlags);
        logd("DataConfigManagerTest -Setup!");
    }

Loading