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

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

Fixed IMS network disconnected when data disabled am: 1d2d57d0 am: bddd2e12

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/2035092

Change-Id: Ie15166f02e1ef14852effd6a08f8a4e703cb7e6c
parents 3a8c5928 bddd2e12
Loading
Loading
Loading
Loading
+32 −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));
    }

    /**
+3 −3
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;
    }

    /**
+17 −16
Original line number Diff line number Diff line
@@ -1331,18 +1331,12 @@ 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;
                }
                int cap = DataUtils.apnTypeToNetworkCapability(apnType);
                if (cap >= 0) {
                    builder.addCapability(cap);
                }
            }
            apnSetting.getApnTypes().stream()
                    .map(DataUtils::apnTypeToNetworkCapability)
                    .filter(cap -> cap >= 0)
                    .forEach(builder::addCapability);
        }

        // Extract network capabilities from the traffic descriptor.
@@ -1377,10 +1371,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 +1399,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);
@@ -1845,7 +1846,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);
    }

+34 −15
Original line number Diff line number Diff line
@@ -1052,7 +1052,7 @@ public class DataNetworkController extends Handler {
        // of them.
        DataEvaluation evaluation = evaluateNetworkRequest(networkRequest,
                DataEvaluationReason.NEW_REQUEST);
        if (evaluation.isDataAllowed()) {
        if (!evaluation.containsDisallowedReasons()) {
            DataProfile dataProfile = evaluation.getCandidateDataProfile();
            if (dataProfile != null) {
                setupDataNetwork(dataProfile, null);
@@ -1235,7 +1235,7 @@ public class DataNetworkController extends Handler {
        }

        // Check whether to allow data in certain situations if data is disallowed for soft reasons
        if (evaluation.isDataAllowed()) {
        if (!evaluation.containsDisallowedReasons()) {
            evaluation.addDataAllowedReason(DataAllowedReason.NORMAL);
        } else if (!evaluation.containsHardDisallowedReasons()) {
            // Check if request is MMS and MMS is always allowed
@@ -1248,12 +1248,7 @@ public class DataNetworkController extends Handler {
            if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
                evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
            } else if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                int apnType = DataUtils.networkCapabilityToApnType(
                        networkRequest.getApnTypeNetworkCapability());
                Set<Integer> meteredApns = mServiceState.getDataRoaming()
                        ? mDataConfigManager.getMeteredApnTypesWhenRoaming()
                        : mDataConfigManager.getMeteredApnTypes();
                if (!meteredApns.contains(apnType)) {
                if (!networkRequest.isMeteredRequest()) {
                    evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
                }
            }
@@ -1280,7 +1275,7 @@ public class DataNetworkController extends Handler {
            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_THROTTLED);
        }

        if (evaluation.isDataAllowed()) {
        if (!evaluation.containsDisallowedReasons()) {
            evaluation.setCandidateDataProfile(dataProfile);
        }

@@ -1332,7 +1327,7 @@ public class DataNetworkController extends Handler {
            // all the requests in the list have the same capabilities, we can only evaluate one
            // of them.
            DataEvaluation evaluation = evaluateNetworkRequest(requestList.get(0), reason);
            if (evaluation.isDataAllowed()) {
            if (!evaluation.containsDisallowedReasons()) {
                DataProfile dataProfile = evaluation.getCandidateDataProfile();
                if (dataProfile != null) {
                    setupDataNetwork(dataProfile, null);
@@ -1432,8 +1427,32 @@ public class DataNetworkController extends Handler {
            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_PROFILE_NOT_PREFERRED);
        }

        if (evaluation.isDataAllowed()) {
        // Check whether if there are any reason we should tear down the network.
        if (!evaluation.containsDisallowedReasons()) {
            // The data is allowed in the current condition.
            evaluation.addDataAllowedReason(DataAllowedReason.NORMAL);
        } else if (!evaluation.containsHardDisallowedReasons()) {
            // If there are reasons we should tear down the network, check if those are hard reasons
            // or soft reasons. In some scenarios, we can make exceptions if they are soft
            // disallowed reasons.

            // Check if request is unmetered (WiFi or unmetered APN)
            if (dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
                evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
            } else {
                boolean unmeteredNetwork = !mDataConfigManager.isAnyMeteredCapability(
                        dataNetwork.getNetworkCapabilities()
                                .getCapabilities(), mServiceState.getDataRoaming());
                if (unmeteredNetwork) {
                    evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
                }
            }

            // Check if request is restricted
            if (!dataNetwork.getNetworkCapabilities().hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
                evaluation.addDataAllowedReason(DataAllowedReason.RESTRICTED_REQUEST);
            }
        }

        log("Evaluated " + dataNetwork + ", " + evaluation.toString());
@@ -1455,7 +1474,7 @@ public class DataNetworkController extends Handler {
        for (DataNetwork dataNetwork : mDataNetworkList) {
            if (dataNetwork.isConnecting() || dataNetwork.isConnected()) {
                DataEvaluation dataEvaluation = evaluateDataNetwork(dataNetwork, reason);
                if (!dataEvaluation.isDataAllowed()) {
                if (dataEvaluation.containsDisallowedReasons()) {
                    tearDownGracefully(dataNetwork, getTearDownReason(dataEvaluation));
                }
            }
@@ -1531,7 +1550,7 @@ public class DataNetworkController extends Handler {
     * @return The tear down reason.
     */
    private @TearDownReason int getTearDownReason(@NonNull DataEvaluation dataEvaluation) {
        if (!dataEvaluation.isDataAllowed()) {
        if (dataEvaluation.containsDisallowedReasons()) {
            switch (dataEvaluation.getDataDisallowedReasons().get(0)) {
                case DATA_DISABLED:
                    return DataNetwork.TEAR_DOWN_REASON_DATA_DISABLED;
@@ -1992,7 +2011,7 @@ public class DataNetworkController extends Handler {

        DataEvaluation evaluation = evaluateNetworkRequest(
                telephonyNetworkRequest, DataEvaluationReason.DATA_RETRY);
        if (evaluation.isDataAllowed()) {
        if (!evaluation.containsDisallowedReasons()) {
            DataProfile dataProfile = dataSetupRetryEntry.dataProfile;
            if (dataProfile == null) {
                dataProfile = evaluation.getCandidateDataProfile();
@@ -2286,7 +2305,7 @@ public class DataNetworkController extends Handler {
                }

                DataEvaluation dataEvaluation = evaluateDataNetworkHandover(dataNetwork);
                if (dataEvaluation.isDataAllowed()) {
                if (!dataEvaluation.containsDisallowedReasons()) {
                    logl("Start handover " + dataNetwork + " to "
                            + AccessNetworkConstants.transportTypeToString(preferredTransport));
                    dataNetwork.startHandover(preferredTransport, null);
+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