Merge "Add indexOf method"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index bcbee07..a3bfbce 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -27,6 +27,10 @@
// included in the bootclasspath, they could incorrectly be included in the SDK documentation even
// though they are not in the current.txt files.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
java_library {
name: "net-utils-device-common",
srcs: [
@@ -73,6 +77,7 @@
host_supported: true,
visibility: [
"//frameworks/libs/net/common/tests:__subpackages__",
+ "//frameworks/libs/net/client-libs/tests:__subpackages__",
],
static_libs: [
"kotlin-test"
diff --git a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
index 6e8c6fe..e5bb58d 100644
--- a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
@@ -66,6 +66,28 @@
}
/**
+ * @return True if all elements satisfy the predicate, false otherwise.
+ * Note that means this always returns true for empty collections.
+ */
+ public static <T> boolean all(@NonNull Collection<T> elem, @NonNull Predicate<T> predicate) {
+ for (final T e : elem) {
+ if (!predicate.test(e)) return false;
+ }
+ return true;
+
+ }
+ /**
+ * @return True if any element satisfies the predicate, false otherwise.
+ * Note that means this always returns false for empty collections.
+ */
+ public static <T> boolean any(@NonNull Collection<T> elem, @NonNull Predicate<T> predicate) {
+ for (final T e : elem) {
+ if (predicate.test(e)) return true;
+ }
+ return false;
+ }
+
+ /**
* @return True if there exists at least one element in the sparse array for which
* condition {@code predicate}
*/
diff --git a/staticlibs/framework/com/android/net/module/util/NetUtils.java b/staticlibs/framework/com/android/net/module/util/NetUtils.java
index 4331b65..f08257a 100644
--- a/staticlibs/framework/com/android/net/module/util/NetUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/NetUtils.java
@@ -23,6 +23,7 @@
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.Collection;
/**
@@ -67,4 +68,44 @@
}
return bestRoute;
}
+
+ /**
+ * Get InetAddress masked with prefixLength. Will never return null.
+ * @param address the IP address to mask with
+ * @param prefixLength the prefixLength used to mask the IP
+ */
+ public static InetAddress getNetworkPart(InetAddress address, int prefixLength) {
+ byte[] array = address.getAddress();
+ maskRawAddress(array, prefixLength);
+
+ InetAddress netPart = null;
+ try {
+ netPart = InetAddress.getByAddress(array);
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("getNetworkPart error - " + e.toString());
+ }
+ return netPart;
+ }
+
+ /**
+ * Masks a raw IP address byte array with the specified prefix length.
+ */
+ public static void maskRawAddress(byte[] array, int prefixLength) {
+ if (prefixLength < 0 || prefixLength > array.length * 8) {
+ throw new RuntimeException("IP address with " + array.length
+ + " bytes has invalid prefix length " + prefixLength);
+ }
+
+ int offset = prefixLength / 8;
+ int remainder = prefixLength % 8;
+ byte mask = (byte) (0xFF << (8 - remainder));
+
+ if (offset < array.length) array[offset] = (byte) (array[offset] & mask);
+
+ offset++;
+
+ for (; offset < array.length; offset++) {
+ array[offset] = 0;
+ }
+ }
}
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkIdentityUtils.java b/staticlibs/framework/com/android/net/module/util/NetworkIdentityUtils.java
new file mode 100644
index 0000000..94e6017
--- /dev/null
+++ b/staticlibs/framework/com/android/net/module/util/NetworkIdentityUtils.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * Utilities to examine {@link android.net.NetworkIdentity}.
+ */
+public class NetworkIdentityUtils {
+ /**
+ * Scrub given IMSI on production builds.
+ */
+ @NonNull
+ public static String scrubSubscriberId(@Nullable String subscriberId) {
+ if (subscriberId != null) {
+ // TODO: parse this as MCC+MNC instead of hard-coding
+ return subscriberId.substring(0, Math.min(6, subscriberId.length())) + "...";
+ } else {
+ return "null";
+ }
+ }
+
+ /**
+ * Scrub given IMSI on production builds.
+ */
+ @Nullable
+ public static String[] scrubSubscriberIds(@Nullable String[] subscriberIds) {
+ if (subscriberIds == null) return null;
+ final String[] res = new String[subscriberIds.length];
+ for (int i = 0; i < res.length; i++) {
+ res[i] = scrubSubscriberId(subscriberIds[i]);
+ }
+ return res;
+ }
+}
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
index a227505..5f62186 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
@@ -16,7 +16,10 @@
package com.android.net.module.util;
+import android.net.InetAddresses;
+
import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -51,8 +54,6 @@
(byte) 0xff, (byte) 0xff, (byte) 0xff,
};
- public static final int DEFAULT_LINK_MTU = 1500;
-
/**
* ARP constants.
*
@@ -98,7 +99,11 @@
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff);
public static final Inet4Address IPV4_ADDR_ANY = makeInet4Address(
(byte) 0, (byte) 0, (byte) 0, (byte) 0);
-
+ public static final Inet6Address IPV6_ADDR_ANY = makeInet6Address(new byte[]{
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0 });
/**
* IPv6 constants.
*
@@ -112,6 +117,12 @@
public static final int IPV6_SRC_ADDR_OFFSET = 8;
public static final int IPV6_DST_ADDR_OFFSET = 24;
public static final int IPV6_MIN_MTU = 1280;
+ public static final Inet6Address IPV6_ADDR_ALL_NODES_MULTICAST =
+ (Inet6Address) InetAddresses.parseNumericAddress("ff02::1");
+ public static final Inet6Address IPV6_ADDR_ALL_ROUTERS_MULTICAST =
+ (Inet6Address) InetAddresses.parseNumericAddress("ff02::2");
+ public static final Inet6Address IPV6_ADDR_ALL_HOSTS_MULTICAST =
+ (Inet6Address) InetAddresses.parseNumericAddress("ff02::3");
/**
* ICMPv6 constants.
@@ -182,6 +193,16 @@
}
}
+ /**
+ * Make an Inet6Address from 16 bytes in network byte order.
+ */
+ private static Inet6Address makeInet6Address(byte[] bytes) {
+ try {
+ return (Inet6Address) InetAddress.getByAddress(bytes);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("addr must be 16 bytes: this should never happen");
+ }
+ }
private NetworkStackConstants() {
throw new UnsupportedOperationException("This class is not to be instantiated");
}
diff --git a/staticlibs/framework/com/android/net/module/util/ProxyUtils.java b/staticlibs/framework/com/android/net/module/util/ProxyUtils.java
index a7b8393..fdd7dca 100644
--- a/staticlibs/framework/com/android/net/module/util/ProxyUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/ProxyUtils.java
@@ -22,6 +22,8 @@
import java.util.Collections;
import java.util.List;
import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Collection of network common utilities.
@@ -30,6 +32,28 @@
*/
public final class ProxyUtils {
+ public static final int PROXY_VALID = 0;
+ public static final int PROXY_HOSTNAME_EMPTY = 1;
+ public static final int PROXY_HOSTNAME_INVALID = 2;
+ public static final int PROXY_PORT_EMPTY = 3;
+ public static final int PROXY_PORT_INVALID = 4;
+ public static final int PROXY_EXCLLIST_INVALID = 5;
+
+ // Hostname / IP REGEX validation
+ // Matches blank input, ips, and domain names
+ private static final String NAME_IP_REGEX =
+ "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*";
+ private static final Pattern HOSTNAME_PATTERN;
+ private static final String HOSTNAME_REGEXP = "^$|^" + NAME_IP_REGEX + "$";
+ private static final Pattern EXCLLIST_PATTERN;
+ private static final String EXCL_REGEX =
+ "[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*(\\.[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*)*";
+ private static final String EXCLLIST_REGEXP = "^$|^" + EXCL_REGEX + "(," + EXCL_REGEX + ")*$";
+ static {
+ HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
+ EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP);
+ }
+
/** Converts exclusion list from String to List. */
public static List<String> exclusionStringAsList(String exclusionList) {
if (exclusionList == null) {
@@ -45,4 +69,30 @@
}
return TextUtils.join(",", exclusionList);
}
+
+ /**
+ * Validate syntax of hostname, port and exclusion list entries
+ */
+ public static int validate(String hostname, String port, String exclList) {
+ Matcher match = HOSTNAME_PATTERN.matcher(hostname);
+ Matcher listMatch = EXCLLIST_PATTERN.matcher(exclList);
+
+ if (!match.matches()) return PROXY_HOSTNAME_INVALID;
+
+ if (!listMatch.matches()) return PROXY_EXCLLIST_INVALID;
+
+ if (hostname.length() > 0 && port.length() == 0) return PROXY_PORT_EMPTY;
+
+ if (port.length() > 0) {
+ if (hostname.length() == 0) return PROXY_HOSTNAME_EMPTY;
+ int portVal = -1;
+ try {
+ portVal = Integer.parseInt(port);
+ } catch (NumberFormatException ex) {
+ return PROXY_PORT_INVALID;
+ }
+ if (portVal <= 0 || portVal > 0xFFFF) return PROXY_PORT_INVALID;
+ }
+ return PROXY_VALID;
+ }
}
diff --git a/staticlibs/native/bpf_syscall_wrappers/Android.bp b/staticlibs/native/bpf_syscall_wrappers/Android.bp
index ae6eee0..fa90655 100644
--- a/staticlibs/native/bpf_syscall_wrappers/Android.bp
+++ b/staticlibs/native/bpf_syscall_wrappers/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "bpf_syscall_wrappers",
vendor_available: false,
diff --git a/staticlibs/native/netjniutils/Android.bp b/staticlibs/native/netjniutils/Android.bp
index 8417c52..d8e6a04 100644
--- a/staticlibs/native/netjniutils/Android.bp
+++ b/staticlibs/native/netjniutils/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libnetjniutils",
srcs: ["netjniutils.cpp"],
diff --git a/staticlibs/tests/unit/Android.bp b/staticlibs/tests/unit/Android.bp
index c00202e..4ce4b0e 100644
--- a/staticlibs/tests/unit/Android.bp
+++ b/staticlibs/tests/unit/Android.bp
@@ -2,6 +2,10 @@
// Build NetworkStaticLibTests package
//########################################################################
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
android_library {
name: "NetworkStaticLibTestsLib",
srcs: ["src/**/*.java","src/**/*.kt"],
@@ -38,4 +42,3 @@
jarjar_rules: "jarjar-rules.txt",
test_suites: ["device-tests"],
}
-
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
new file mode 100644
index 0000000..0007742
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util
+
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class CollectionUtilsTest {
+ @Test
+ fun testAny() {
+ assertTrue(CollectionUtils.any(listOf("A", "B", "C", "D", "E")) { it == "E" })
+ assertFalse(CollectionUtils.any(listOf("A", "B", "C", "D", "E")) { it == "F" })
+ assertTrue(CollectionUtils.any(listOf("AA", "BBB")) { it.length >= 3 })
+ assertFalse(CollectionUtils.any(listOf("A", "BB", "CCC")) { it.length >= 4 })
+ assertFalse(CollectionUtils.any(listOf("A", "BB", "CCC")) { it.length < 0 })
+ assertFalse(CollectionUtils.any(listOf<String>()) { true })
+ assertFalse(CollectionUtils.any(listOf<String>()) { false })
+ assertTrue(CollectionUtils.any(listOf("A")) { true })
+ assertFalse(CollectionUtils.any(listOf("A")) { false })
+ }
+
+ @Test
+ fun testAll() {
+ assertFalse(CollectionUtils.all(listOf("A", "B", "C", "D", "E")) { it != "E" })
+ assertTrue(CollectionUtils.all(listOf("A", "B", "C", "D", "E")) { it != "F" })
+ assertFalse(CollectionUtils.all(listOf("A", "BB", "CCC")) { it.length > 2 })
+ assertTrue(CollectionUtils.all(listOf("A", "BB", "CCC")) { it.length >= 1 })
+ assertTrue(CollectionUtils.all(listOf("A", "BB", "CCC")) { it.length < 4 })
+ assertTrue(CollectionUtils.all(listOf<String>()) { true })
+ assertTrue(CollectionUtils.all(listOf<String>()) { false })
+ assertTrue(CollectionUtils.all(listOf(1)) { true })
+ assertFalse(CollectionUtils.all(listOf(1)) { false })
+ }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt
new file mode 100644
index 0000000..2904e12
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util
+
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.net.module.util.NetworkIdentityUtils.scrubSubscriberId
+import com.android.net.module.util.NetworkIdentityUtils.scrubSubscriberIds
+import com.android.testutils.assertContainsStringsExactly
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertEquals
+import kotlin.test.assertNull
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkIdentityUtilsTest {
+ @Test
+ fun testScrubSubscriberId() {
+ assertEquals("123456...", scrubSubscriberId("1234567890123"))
+ assertEquals("123456...", scrubSubscriberId("1234567"))
+ assertEquals("123...", scrubSubscriberId("123"))
+ assertEquals("...", scrubSubscriberId(""))
+ assertEquals("null", scrubSubscriberId(null))
+ }
+
+ @Test
+ fun testScrubSubscriberIds() {
+ assertContainsStringsExactly(scrubSubscriberIds(arrayOf("1234567", "", null))!!,
+ "123456...", "...", "null")
+ assertContainsStringsExactly(scrubSubscriberIds(arrayOf("12345"))!!, "12345...")
+ assertContainsStringsExactly(scrubSubscriberIds(arrayOf())!!)
+ assertNull(scrubSubscriberIds(null))
+ }
+}
\ No newline at end of file