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

Commit 09477d88 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topic "mmtel_vops"

* changes:
  Supported network capability MMTEL
  Fixed IMS network disconnected when data disabled
parents 5fd9bb27 84536c72
Loading
Loading
Loading
Loading
+42 −6
Original line number Diff line number Diff line
@@ -424,17 +424,43 @@ public class DataConfigManager extends Handler {
    }

    /**
     * @return The metered APN types when connected to a home network
     * Get the metered network capabilities.
     *
     * @param isRoaming {@code true} for roaming scenario.
     *
     * @return The metered network capabilities when connected to a home network.
     */
    public @NonNull @ApnType Set<Integer> getMeteredApnTypes() {
        return Collections.unmodifiableSet(mMeteredApnTypes);
    public @NonNull @NetCapability Set<Integer> getMeteredNetworkCapabilities(boolean isRoaming) {
        Set<Integer> meteredApnTypes = isRoaming ? mRoamingMeteredApnTypes : mMeteredApnTypes;
        return meteredApnTypes.stream()
                .map(DataUtils::apnTypeToNetworkCapability)
                .filter(cap -> cap >= 0)
                .collect(Collectors.toUnmodifiableSet());
    }

    /**
     * @return The metered APN types when roaming
     * Check if the network capability metered.
     *
     * @param networkCapability The network capability.
     * @param isRoaming {@code true} for roaming scenario.
     * @return {@code true} if the network capability is metered.
     */
    public @NonNull @ApnType Set<Integer> getMeteredApnTypesWhenRoaming() {
        return Collections.unmodifiableSet(mRoamingMeteredApnTypes);
    public boolean isMeteredCapability(@NetCapability int networkCapability, boolean isRoaming) {
        return getMeteredNetworkCapabilities(isRoaming).contains(networkCapability);
    }

    /**
     * Check if the network capabilities are metered. If one of the capabilities is metered, then
     * the capabilities are metered.
     *
     * @param networkCapabilities The network capabilities.
     * @param isRoaming {@code true} for roaming scenario.
     * @return {@code true} if the capabilities are metered.
     */
    public boolean isAnyMeteredCapability(@NonNull @NetCapability int[] networkCapabilities,
            boolean isRoaming) {
        return Arrays.stream(networkCapabilities).boxed()
                .anyMatch(cap -> isMeteredCapability(cap, isRoaming));
    }

    /**
@@ -632,6 +658,15 @@ public class DataConfigManager extends Handler {
                .config_wlan_data_service_conn_persistence_on_restart);
    }

    /**
     * @return {@code true} if tearing down IMS data network should be delayed until the voice call
     * ends.
     */
    public boolean isImsDelayTearDownEnabled() {
        return mCarrierConfig.getBoolean(
                CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL);
    }

    /**
     * @return The bandwidth estimation source.
     */
@@ -903,6 +938,7 @@ public class DataConfigManager extends Handler {
                + shouldPersistIwlanDataNetworksWhenDataServiceRestarted());
        pw.println("Bandwidth estimation source=" + mResources.getString(
                com.android.internal.R.string.config_bandwidthEstimateSource));
        pw.println("isDelayTearDownImsEnabled=" + isImsDelayTearDownEnabled());
        pw.decreaseIndent();
    }
}
+6 −4
Original line number Diff line number Diff line
@@ -120,10 +120,10 @@ public class DataEvaluation {
    }

    /**
     * @return {@code true} if the operation is allowed.
     * @return {@code true} if the evaluation contains disallowed reasons.
     */
    public boolean isDataAllowed() {
        return mDataDisallowedReasons.size() == 0;
    public boolean containsDisallowedReasons() {
        return mDataDisallowedReasons.size() != 0;
    }

    /**
@@ -257,7 +257,9 @@ public class DataEvaluation {
        /** Handover is not allowed by policy. */
        NOT_ALLOWED_BY_POLICY(true),
        /** Data network is not in the right state. */
        ILLEGAL_STATE(true);
        ILLEGAL_STATE(true),
        /** VoPS is not supported by the network. */
        VOPS_NOT_SUPPORTED(true);

        private final boolean mIsHardReason;

+75 −41
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.ValidationStatus;
import android.telephony.DataFailCause;
import android.telephony.DataSpecificRegistrationInfo;
import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PcoData;
@@ -226,6 +227,7 @@ public class DataNetwork extends StateMachine {
                    TEAR_DOWN_REASON_HANDOVER_FAILED,
                    TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED,
                    TEAR_DOWN_REASON_VCN_REQUESTED,
                    TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED,
            })
    public @interface TearDownReason {}

@@ -274,6 +276,9 @@ public class DataNetwork extends StateMachine {
    /** Data network tear down due to VCN service requested. */
    public static final int TEAR_DOWN_REASON_VCN_REQUESTED = 15;

    /** Data network tear down due to VOPS no longer supported. */
    public static final int TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED = 16;

    @IntDef(prefix = {"BANDWIDTH_SOURCE_"},
            value = {
                    BANDWIDTH_SOURCE_UNKNOWN,
@@ -770,22 +775,14 @@ public class DataNetwork extends StateMachine {
        public void enter() {
            logv("Registering all events.");
            mDataConfigManager.registerForConfigUpdate(getHandler(), EVENT_DATA_CONFIG_UPDATED);
            mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                    .registerForDataCallListChanged(getHandler(), EVENT_DATA_STATE_CHANGED);
            if (!mAccessNetworksManager.isInLegacyMode()) {
                mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
            mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
                    getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
                mDataServiceManagers.get(transport)
                        .registerForDataCallListChanged(getHandler(), EVENT_DATA_STATE_CHANGED);
                mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
                        AccessNetworkConstants.TRANSPORT_TYPE_WLAN, getHandler(),
                        EVENT_SERVICE_STATE_CHANGED,
                        AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
                        transport, getHandler(), EVENT_SERVICE_STATE_CHANGED, transport);
            }
            mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler(),
                    EVENT_SERVICE_STATE_CHANGED,
                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
            mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
                    getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);

            // Only add symmetric code here, for example, registering and unregistering.
            // DefaultState.enter() is the starting point in the life cycle of the DataNetwork,
@@ -796,19 +793,14 @@ public class DataNetwork extends StateMachine {
        @Override
        public void exit() {
            logv("Unregistering all events.");
            mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
                    getHandler());
            mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler());

            if (!mAccessNetworksManager.isInLegacyMode()) {
                mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
                mDataServiceManagers.get(transport)
                        .unregisterForDataCallListChanged(getHandler());
                mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
                        AccessNetworkConstants.TRANSPORT_TYPE_WLAN, getHandler());
                        transport, getHandler());
            }
            mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                    .unregisterForDataCallListChanged(getHandler());
            mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
                    getHandler());
            mDataConfigManager.unregisterForConfigUpdate(getHandler());
        }

@@ -1331,16 +1323,39 @@ public class DataNetwork extends StateMachine {
        builder.setSubscriptionIds(Collections.singleton(mSubId));

        ApnSetting apnSetting = mDataProfile.getApnSetting();
        boolean meteredApn = false;

        if (apnSetting != null) {
            for (int apnType : apnSetting.getApnTypes()) {
                if (!(roaming ? mDataConfigManager.getMeteredApnTypesWhenRoaming()
                        : mDataConfigManager.getMeteredApnTypes()).contains(apnType)) {
                    meteredApn = true;
            apnSetting.getApnTypes().stream()
                    .map(DataUtils::apnTypeToNetworkCapability)
                    .filter(cap -> cap >= 0)
                    .forEach(builder::addCapability);
        }

        // If voice call is on-going, do not change MMTEL capability, which is a immutable
        // capability. Changing it will result in re-recreating network agent below, and the voice
        // call will drop. Whether tearing down an IMS network or not when VoPS is lost
        if (mPhone.getImsPhone() != null && mPhone.getImsPhone().getCallTracker().getState()
                != PhoneConstants.State.IDLE && mNetworkCapabilities != null
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
            // Previous capability has MMTEL, so add it again.
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
        } else {
            // 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 = mPhone.getServiceStateTracker().getServiceState()
                            .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
                                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
                    if (nri != null) {
                        DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
                        // Check if VoPS is supported by the network.
                        if (dsri != null && dsri.getVopsSupportInfo() != null
                                && !dsri.getVopsSupportInfo().isVopsSupported()) {
                            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
                        }
                    }
                int cap = DataUtils.apnTypeToNetworkCapability(apnType);
                if (cap >= 0) {
                    builder.addCapability(cap);
                }
            }
        }
@@ -1377,10 +1392,6 @@ public class DataNetwork extends StateMachine {
            }
        }

        // TODO: Support NET_CAPABILITY_NOT_METERED when non-restricted data is for unmetered use
        if (!meteredApn) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        }
        // TODO: Support NET_CAPABILITY_NOT_RESTRICTED
        if (!mCongested) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
@@ -1409,6 +1420,17 @@ public class DataNetwork extends StateMachine {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

        Set<Integer> meteredCapabilities = mDataConfigManager
                .getMeteredNetworkCapabilities(roaming);
        boolean unmeteredNetwork = meteredCapabilities.stream().noneMatch(
                Arrays.stream(builder.build().getCapabilities()).boxed()
                        .collect(Collectors.toSet())::contains);

        // TODO: Support NET_CAPABILITY_NOT_METERED when non-restricted data is for unmetered use
        if (unmeteredNetwork) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        }

        // Set the bandwidth information.
        builder.setLinkDownstreamBandwidthKbps(mNetworkBandwidth.downlinkBandwidthKbps);
        builder.setLinkUpstreamBandwidthKbps(mNetworkBandwidth.uplinkBandwidthKbps);
@@ -1442,12 +1464,13 @@ public class DataNetwork extends StateMachine {
                mNetworkCapabilities = nc;
                mNetworkAgent = createNetworkAgent();
                mNetworkAgent.markConnected();
            }

            } else {
                // Now we need to inform connectivity service and data network controller
                // about the capabilities changed.
                mNetworkCapabilities = nc;
                mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
            }

            removeUnsatisfiedNetworkRequests();
            mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                    .onNetworkCapabilitiesChanged(DataNetwork.this));
@@ -1809,6 +1832,15 @@ public class DataNetwork extends StateMachine {

    private void onTearDown(@TearDownReason int reason) {
        logl("onTearDown: reason=" + tearDownReasonToString(reason));
        if (mDataConfigManager.isImsDelayTearDownEnabled()
                && 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.");
            return;
        }

        // TODO: Need to support DataService.REQUEST_REASON_SHUTDOWN
        mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
                DataService.REQUEST_REASON_NORMAL, null);
@@ -1845,7 +1877,7 @@ public class DataNetwork extends StateMachine {
        }
        logl("tearDownWithCondition: reason=" + tearDownReasonToString(reason) + ", timeout="
                + timeoutMillis + "ms.");
        sendMessageDelayed(EVENT_TEAR_DOWN_NETWORK, timeoutMillis);
        sendMessageDelayed(EVENT_TEAR_DOWN_NETWORK, reason, timeoutMillis);
        return () -> this.tearDown(reason);
    }

@@ -2474,6 +2506,8 @@ public class DataNetwork extends StateMachine {
                return "TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED";
            case TEAR_DOWN_REASON_VCN_REQUESTED:
                return "TEAR_DOWN_REASON_VCN_REQUESTED";
            case TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED:
                return "TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED";
            default:
                return "UNKNOWN(" + reason + ")";
        }
+112 −15

File changed.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Diff line number Diff line
@@ -169,6 +169,9 @@ public class DataSettingsManager extends Handler {
        mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_CARRIER, true);
        mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_THERMAL, true);

        mIsDataEnabled = isDataEnabled(ApnSetting.TYPE_ALL);
        log("mIsDataEnabled=" + mIsDataEnabled);

        // Instead of calling onRegisterAllEvents directly from the constructor, send the event.
        // The reason is that getImsPhone is null when we are still in the constructor here.
        sendEmptyMessage(EVENT_REGISTER_ALL_EVENTS);
@@ -220,6 +223,7 @@ public class DataSettingsManager extends Handler {
                if (isStandAloneOpportunistic(mSubId, mPhone.getContext()) && !enabled) return;
                boolean changed = GlobalSettingsHelper.setInt(mPhone.getContext(),
                        Settings.Global.MOBILE_DATA, mSubId, (enabled ? 1 : 0));
                log("Set user data enabled to " + enabled + ", changed=" + changed);
                if (changed) {
                    logl("UserDataEnabled changed to " + enabled);
                    mPhone.notifyUserMobileDataStateChanged(enabled);
@@ -304,6 +308,7 @@ public class DataSettingsManager extends Handler {
            case EVENT_UPDATE_DATA_ENABLED: {
                boolean prevDataEnabled = mIsDataEnabled;
                mIsDataEnabled = isDataEnabled(ApnSetting.TYPE_ALL);
                log("mIsDataEnabled=" + mIsDataEnabled + ", prevDataEnabled=" + prevDataEnabled);
                if (prevDataEnabled != mIsDataEnabled) {
                    notifyDataEnabledChanged(mIsDataEnabled, (int) msg.obj);
                }
Loading