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

Commit 1064e2fb authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Extend HandoverRule with ApnType"

parents ea54ce3f 6a147c63
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();
    }

}