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

Commit faeb8267 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Extend HandoverRule with ApnType" am: 1064e2fb

parents 156c1737 1064e2fb
Loading
Loading
Loading
Loading
+39 −12
Original line number Diff line number Diff line
@@ -578,6 +578,8 @@ public class DataNetworkController extends Handler {

        private static final String RULE_TAG_TYPE = "type";

        private static final String RULE_TAG_CAPABILITIES = "capabilities";

        private static final String RULE_TAG_ROAMING = "roaming";

        /** Handover rule type. */
@@ -589,6 +591,12 @@ public class DataNetworkController extends Handler {
        /** The applicable target access networks for handover. */
        public final @NonNull @RadioAccessNetworkType Set<Integer> targetAccessNetworks;

        /**
         * The network capabilities to any of which this handover rule applies.
         * If is empty, then capability is ignored as a rule matcher.
         */
        public final @NonNull @NetCapability Set<Integer> networkCapabilities;

        /** {@code true} indicates this policy is only applicable when the device is roaming. */
        public final boolean isOnlyForRoaming;

@@ -604,7 +612,7 @@ public class DataNetworkController extends Handler {
                throw new IllegalArgumentException("illegal rule " + ruleString);
            }

            Set<Integer> source = null, target = null;
            Set<Integer> source = null, target = null, capabilities = Collections.emptySet();
            int type = 0;
            boolean roaming = false;

@@ -641,6 +649,9 @@ public class DataNetworkController extends Handler {
                                throw new IllegalArgumentException("unexpected rule type " + value);
                            }
                            break;
                        case RULE_TAG_CAPABILITIES:
                            capabilities = DataUtils.getNetworkCapabilitiesFromString(value);
                            break;
                        case RULE_TAG_ROAMING:
                            roaming = Boolean.parseBoolean(value);
                            break;
@@ -654,7 +665,7 @@ public class DataNetworkController extends Handler {
                }
            }

            if (source == null || target == null) {
            if (source == null || target == null || source.isEmpty() || target.isEmpty()) {
                throw new IllegalArgumentException("Need to specify both source and target. "
                        + "\"" + ruleString + "\"");
            }
@@ -674,6 +685,11 @@ public class DataNetworkController extends Handler {
                        + "\"" + ruleString + "\"");
            }

            if (capabilities != null && capabilities.contains(-1)) {
                throw new IllegalArgumentException("Network capabilities contains unknown. "
                            + "\"" + ruleString + "\"");
            }

            if (!source.contains(AccessNetworkType.IWLAN)
                    && !target.contains(AccessNetworkType.IWLAN)) {
                throw new IllegalArgumentException("IWLAN must be specified in either source or "
@@ -683,6 +699,7 @@ public class DataNetworkController extends Handler {
            sourceAccessNetworks = source;
            targetAccessNetworks = target;
            this.type = type;
            networkCapabilities = capabilities;
            isOnlyForRoaming = roaming;
        }

@@ -692,7 +709,9 @@ public class DataNetworkController extends Handler {
                    : "disallowed") + ", source=" + sourceAccessNetworks.stream()
                    .map(AccessNetworkType::toString).collect(Collectors.joining("|"))
                    + ", target=" + targetAccessNetworks.stream().map(AccessNetworkType::toString)
                    .collect(Collectors.joining("|")) + ", isRoaming=" + isOnlyForRoaming + "]";
                    .collect(Collectors.joining("|")) + ", isRoaming=" + isOnlyForRoaming
                    + ", capabilities=" + DataUtils.networkCapabilitiesToString(networkCapabilities)
                    + "]";
        }
    }

@@ -1609,10 +1628,12 @@ public class DataNetworkController extends Handler {
                getDataNetworkType(dataNetwork.getTransport()));
        int targetAccessNetwork = DataUtils.networkTypeToAccessNetworkType(
                getDataNetworkType(DataUtils.getTargetTransport(dataNetwork.getTransport())));
        NetworkCapabilities capabilities = dataNetwork.getNetworkCapabilities();
        log("evaluateDataNetworkHandover: "
                + "source=" + AccessNetworkType.toString(sourceAccessNetwork)
                + ", target=" + AccessNetworkType.toString(targetAccessNetwork)
                + ", ServiceState=" + mServiceState);
                + ", ServiceState=" + mServiceState
                + ", capabilities=" + capabilities);

        // Matching the rules by the configured order. Bail out if find first matching rule.
        for (HandoverRule rule : handoverRules) {
@@ -1621,6 +1642,11 @@ public class DataNetworkController extends Handler {

            if (rule.sourceAccessNetworks.contains(sourceAccessNetwork)
                    && rule.targetAccessNetworks.contains(targetAccessNetwork)) {
                // if no capability rule specified, data network capability is considered matched.
                // otherwise, any capabilities overlap is also considered matched.
                if (rule.networkCapabilities.isEmpty()
                        || rule.networkCapabilities.stream()
                        .anyMatch(capabilities::hasCapability)) {
                    log("evaluateDataNetworkHandover: Matched " + rule);
                    if (rule.type == HandoverRule.RULE_TYPE_DISALLOWED) {
                        dataEvaluation.addDataDisallowedReason(
@@ -1632,6 +1658,7 @@ public class DataNetworkController extends Handler {
                    return dataEvaluation;
                }
            }
        }

        log("evaluateDataNetworkHandover: Did not find matching rule. " + dataEvaluation);
        // Allow handover anyway if no rule is found.
+4 −6
Original line number Diff line number Diff line
@@ -402,16 +402,14 @@ public class DataRetryManager extends Handler {
                String key = tokens[0].trim();
                String value = tokens[1].trim();
                if (key.equals(RULE_TAG_CAPABILITIES)) {
                    mNetworkCapabilities = Arrays.stream(value.split("\\s*\\|\\s*"))
                            .map(String::trim)
                            .map(DataUtils::getNetworkCapabilityFromString)
                            .collect(Collectors.toSet());
                    mNetworkCapabilities = DataUtils.getNetworkCapabilitiesFromString(value);
                }
            }

            if (mNetworkCapabilities.size() == 0 && mFailCauses.size() == 0) {
            if (mFailCauses.isEmpty() && (mNetworkCapabilities.isEmpty()
                    || mNetworkCapabilities.contains(-1))) {
                throw new IllegalArgumentException("illegal rule " + ruleString
                        + ". Should have either network capabilities or fail causes.");
                            + ". Should have either valid network capabilities or fail causes.");
            }
        }

+23 −1
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ import com.android.internal.telephony.data.DataNetworkController.NetworkRequestL
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
@@ -89,6 +91,26 @@ public class DataUtils {
        }
    }

    /**
     * Get Set of network capabilities from string joined by {@code |}, space is ignored.
     * If input string contains unknown capability or malformatted(e.g. empty string), -1 is
     * included in the returned set.
     *
     * @param capabilitiesString capability strings joined by {@code |}
     * @return Set of capabilities
     */
    public static @NetCapability Set<Integer> getNetworkCapabilitiesFromString(
            @NonNull String capabilitiesString) {
        // e.g. "IMS|" is not allowed
        if (!capabilitiesString.matches("(\\s*[a-zA-Z]+\\s*)(\\|\\s*[a-zA-Z]+\\s*)*")) {
            return Collections.singleton(-1);
        }
        return Arrays.stream(capabilitiesString.split("\\s*\\|\\s*"))
                .map(String::trim)
                .map(DataUtils::getNetworkCapabilityFromString)
                .collect(Collectors.toSet());
    }

    /**
     * Convert a network capability to string.
     *
@@ -153,7 +175,7 @@ public class DataUtils {
     * @return Network capabilities in string format.
     */
    public static @NonNull String networkCapabilitiesToString(
            @NetCapability @Nullable List<Integer> netCaps) {
            @NetCapability @Nullable Collection<Integer> netCaps) {
        if (netCaps == null || netCaps.isEmpty()) return "";
        return "[" + netCaps.stream()
                .map(DataUtils::networkCapabilityToString)
+35 −3
Original line number Diff line number Diff line
@@ -1096,6 +1096,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
                AccessNetworkType.IWLAN);
        assertThat(handoverRule.type).isEqualTo(HandoverRule.RULE_TYPE_ALLOWED);
        assertThat(handoverRule.isOnlyForRoaming).isFalse();
        assertThat(handoverRule.networkCapabilities).isEmpty();

        handoverRule = new HandoverRule("source=   NGRAN|     IWLAN, "
                + "target  =    EUTRAN,    type  =    disallowed ");
@@ -1104,12 +1105,16 @@ public class DataNetworkControllerTest extends TelephonyTest {
        assertThat(handoverRule.targetAccessNetworks).containsExactly(AccessNetworkType.EUTRAN);
        assertThat(handoverRule.type).isEqualTo(HandoverRule.RULE_TYPE_DISALLOWED);
        assertThat(handoverRule.isOnlyForRoaming).isFalse();
        assertThat(handoverRule.networkCapabilities).isEmpty();

        handoverRule = new HandoverRule("source=   IWLAN, "
                + "target  =    EUTRAN,    type  =    disallowed, roaming = true");
                + "target  =    EUTRAN,    type  =    disallowed, roaming = true,"
                + " capabilities = IMS | EIMS ");
        assertThat(handoverRule.sourceAccessNetworks).containsExactly(AccessNetworkType.IWLAN);
        assertThat(handoverRule.targetAccessNetworks).containsExactly(AccessNetworkType.EUTRAN);
        assertThat(handoverRule.type).isEqualTo(HandoverRule.RULE_TYPE_DISALLOWED);
        assertThat(handoverRule.networkCapabilities).containsExactly(
                NetworkCapabilities.NET_CAPABILITY_IMS, NetworkCapabilities.NET_CAPABILITY_EIMS);
        assertThat(handoverRule.isOnlyForRoaming).isTrue();

        assertThrows(IllegalArgumentException.class,
@@ -1129,6 +1134,19 @@ public class DataNetworkControllerTest extends TelephonyTest {

        assertThrows(IllegalArgumentException.class,
                () -> new HandoverRule("source=IWLAN, target=WTFRAN, type=allowed"));

        assertThrows(IllegalArgumentException.class,
                () -> new HandoverRule("source=IWLAN, target=|, type=allowed"));

        assertThrows(IllegalArgumentException.class,
                () -> new HandoverRule("source=GERAN, target=IWLAN, type=allowed, capabilities=|"));

        assertThrows(IllegalArgumentException.class,
                () -> new HandoverRule("source=GERAN, target=IWLAN, type=allowed, capabilities="));

        assertThrows(IllegalArgumentException.class,
                () -> new HandoverRule("source=GERAN, target=IWLAN, type=allowed, "
                        + "capabilities=wtf"));
    }

    @Test
@@ -1300,7 +1318,8 @@ public class DataNetworkControllerTest extends TelephonyTest {
    @Test
    public void testHandoverDataNetworkNotAllowedByPolicy() throws Exception {
        mCarrierConfig.putStringArray(CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY,
                new String[]{"source=EUTRAN, target=IWLAN, type=disallowed"});
                new String[]{"source=EUTRAN, target=IWLAN, type=disallowed, capabilities=MMS|IMS",
                        "source=IWLAN, target=EUTRAN, type=disallowed, capabilities=MMS"});
        // Force data config manager to reload the carrier config.
        mDataNetworkControllerUT.getDataConfigManager().obtainMessage(
                1/*EVENT_CARRIER_CONFIG_CHANGED*/).sendToTarget();
@@ -1327,6 +1346,19 @@ public class DataNetworkControllerTest extends TelephonyTest {
                NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
        assertThat(dataNetworkList.get(0).getTransport())
                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);

        // test IWLAN -> EUTRAN no need to tear down because the disallowed rule only applies to MMS
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
        mDataNetworkControllerUT.obtainMessage(21/*EVENT_PREFERRED_TRANSPORT_CHANGED*/,
                NetworkCapabilities.NET_CAPABILITY_IMS, 0).sendToTarget();
        // After this, IMS data network should be disconnected, and DNC should attempt to
        // establish a new one on IWLAN
        processAllMessages();
        DataNetwork dataNetwork = getDataNetworks().get(0);
        // Verify that IWWAN handover succeeded.
        assertThat(dataNetwork.getTransport()).isEqualTo(
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
    }

    @Test
+28 −0
Original line number Diff line number Diff line
@@ -96,4 +96,32 @@ public class DataUtilsTest extends TelephonyTest {
                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
    }

    @Test
    public void testGetNetworkCapabilitiesFromString() {
        String normal = " MMS  ";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(normal)).containsExactly(
                NetworkCapabilities.NET_CAPABILITY_MMS);
        String normal2 = "MMS|IMS";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(normal2)).containsExactly(
                NetworkCapabilities.NET_CAPABILITY_MMS, NetworkCapabilities.NET_CAPABILITY_IMS);
        String normal3 = " MMS |IMS ";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(normal3)).containsExactly(
                NetworkCapabilities.NET_CAPABILITY_MMS, NetworkCapabilities.NET_CAPABILITY_IMS);

        String containsUnknown = "MMS |IMS | what";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(containsUnknown)
                .contains(-1)).isTrue();

        String malFormatted = "";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted).contains(-1)).isTrue();
        String malFormatted2 = " ";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted2).contains(-1)).isTrue();
        String malFormatted3 = "MMS |IMS |";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted3).contains(-1)).isTrue();
        String composedDelim = " | ||";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(composedDelim).contains(-1)).isTrue();
        String malFormatted4 = "mms||ims";
        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted4).contains(-1)).isTrue();
    }

}