Merge "[CC08] Remove expectCallback*"
diff --git a/staticlibs/device/com/android/net/module/util/NetworkMonitorUtils.java b/staticlibs/device/com/android/net/module/util/NetworkMonitorUtils.java
index f6cd044..5a4412f 100644
--- a/staticlibs/device/com/android/net/module/util/NetworkMonitorUtils.java
+++ b/staticlibs/device/com/android/net/module/util/NetworkMonitorUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.net.module.util;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
@@ -102,9 +103,12 @@
      *                                networks.
      * @param nc Network capabilities of the network to test.
      */
-    public static boolean isValidationRequired(boolean isVpnValidationRequired,
+    public static boolean isValidationRequired(boolean isDunValidationRequired,
+            boolean isVpnValidationRequired,
             @NonNull final NetworkCapabilities nc) {
-        // TODO: Consider requiring validation for DUN networks.
+        if (isDunValidationRequired && nc.hasCapability(NET_CAPABILITY_DUN)) {
+            return true;
+        }
         if (!nc.hasCapability(NET_CAPABILITY_NOT_VPN)) {
             return isVpnValidationRequired;
         }
diff --git a/staticlibs/framework/com/android/net/module/util/ByteUtils.java b/staticlibs/framework/com/android/net/module/util/ByteUtils.java
new file mode 100644
index 0000000..290ed46
--- /dev/null
+++ b/staticlibs/framework/com/android/net/module/util/ByteUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 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;
+
+/**
+ * Byte utility functions.
+ * @hide
+ */
+public class ByteUtils {
+    /**
+     * Returns the index of the first appearance of the value {@code target} in {@code array}.
+     *
+     * @param array an array of {@code byte} values, possibly empty
+     * @param target a primitive {@code byte} value
+     * @return the least index {@code i} for which {@code array[i] == target}, or {@code -1} if no
+     *     such index exists.
+     */
+    public static int indexOf(@NonNull byte[] array, byte target) {
+        return indexOf(array, target, 0, array.length);
+    }
+
+    private static int indexOf(byte[] array, byte target, int start, int end) {
+        for (int i = start; i < end; i++) {
+            if (array[i] == target) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the values from each provided array combined into a single array. For example, {@code
+     * concat(new byte[] {a, b}, new byte[] {}, new byte[] {c}} returns the array {@code {a, b, c}}.
+     *
+     * @param arrays zero or more {@code byte} arrays
+     * @return a single array containing all the values from the source arrays, in order
+     */
+    public static byte[] concat(@NonNull byte[]... arrays) {
+        int length = 0;
+        for (byte[] array : arrays) {
+            length += array.length;
+        }
+        byte[] result = new byte[length];
+        int pos = 0;
+        for (byte[] array : arrays) {
+            System.arraycopy(array, 0, result, pos, array.length);
+            pos += array.length;
+        }
+        return result;
+    }
+}
diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h b/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
index 4429164..157f210 100644
--- a/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
+++ b/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
@@ -115,23 +115,16 @@
     return kernelVersion() >= KVER(major, minor, sub);
 }
 
-#define SKIP_IF_BPF_SUPPORTED                              \
-    do {                                                   \
-        if (android::bpf::isAtLeastKernelVersion(4, 9, 0)) \
-            GTEST_SKIP() << "Skip: bpf is supported.";     \
-    } while (0)
-
 #define SKIP_IF_BPF_NOT_SUPPORTED                           \
     do {                                                    \
         if (!android::bpf::isAtLeastKernelVersion(4, 9, 0)) \
             GTEST_SKIP() << "Skip: bpf is not supported.";  \
     } while (0)
 
-#define SKIP_IF_EXTENDED_BPF_NOT_SUPPORTED                               \
-    do {                                                                 \
-        if (!android::bpf::isAtLeastKernelVersion(4, 14, 0))             \
-            GTEST_SKIP() << "Skip: extended bpf feature not supported."; \
-    } while (0)
+// Only used by tm-mainline-prod's system/netd/tests/bpf_base_test.cpp
+// but platform and platform tests aren't expected to build/work in tm-mainline-prod
+// so we can just trivialize this
+#define SKIP_IF_EXTENDED_BPF_NOT_SUPPORTED
 
 #define SKIP_IF_XDP_NOT_SUPPORTED                           \
     do {                                                    \
diff --git a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
index 56bc7d0..c652c76 100644
--- a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
+++ b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
@@ -138,10 +138,6 @@
 static int (*bpf_map_delete_elem_unsafe)(const struct bpf_map_def* map,
                                          const void* key) = (void*)BPF_FUNC_map_delete_elem;
 
-static int (*bpf_for_each_map_elem)(const struct bpf_map_def* map, void *callback_fn,
-                                    void *callback_ctx, unsigned long long flags) = (void*)
-        BPF_FUNC_for_each_map_elem;
-
 #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)  \
         struct ____btf_map_##name {                     \
                 type_key key;                           \
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/ByteUtilsTests.kt b/staticlibs/tests/unit/src/com/android/net/module/util/ByteUtilsTests.kt
new file mode 100644
index 0000000..e58adad
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/ByteUtilsTests.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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 com.android.net.module.util.ByteUtils.indexOf
+import com.android.net.module.util.ByteUtils.concat
+import org.junit.Test
+import kotlin.test.assertContentEquals
+import kotlin.test.assertEquals
+import kotlin.test.assertNotSame
+
+class ByteUtilsTests {
+    private val EMPTY = byteArrayOf()
+    private val ARRAY1 = byteArrayOf(1)
+    private val ARRAY234 = byteArrayOf(2, 3, 4)
+
+    @Test
+    fun testIndexOf() {
+        assertEquals(-1, indexOf(EMPTY, 1))
+        assertEquals(-1, indexOf(ARRAY1, 2))
+        assertEquals(-1, indexOf(ARRAY234, 1))
+        assertEquals(0, indexOf(byteArrayOf(-1), -1))
+        assertEquals(0, indexOf(ARRAY234, 2))
+        assertEquals(1, indexOf(ARRAY234, 3))
+        assertEquals(2, indexOf(ARRAY234, 4))
+        assertEquals(1, indexOf(byteArrayOf(2, 3, 2, 3), 3))
+    }
+
+    @Test
+    fun testConcat() {
+        assertContentEquals(EMPTY, concat())
+        assertContentEquals(EMPTY, concat(EMPTY))
+        assertContentEquals(EMPTY, concat(EMPTY, EMPTY, EMPTY))
+        assertContentEquals(ARRAY1, concat(ARRAY1))
+        assertNotSame(ARRAY1, concat(ARRAY1))
+        assertContentEquals(ARRAY1, concat(EMPTY, ARRAY1, EMPTY))
+        assertContentEquals(byteArrayOf(1, 1, 1), concat(ARRAY1, ARRAY1, ARRAY1))
+        assertContentEquals(byteArrayOf(1, 2, 3, 4), concat(ARRAY1, ARRAY234))
+    }
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
index 7e92af1..7b5ad01 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
@@ -63,6 +63,7 @@
 
         try {
             val connInfo = wifiManager.connectionInfo
+            Log.d(TAG, "connInfo=" + connInfo)
             if (connInfo == null || connInfo.networkId == -1) {
                 clearWifiBlocklist()
                 val pfd = getInstrumentation().uiAutomation.executeShellCommand("svc wifi enable")
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java b/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
index ea89eda..ce55fdc 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
@@ -20,6 +20,7 @@
 import android.text.TextUtils;
 import android.util.Pair;
 
+import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -128,7 +129,7 @@
         final Pair<Integer, Integer> v1 = getMajorMinorVersion(s1);
         final Pair<Integer, Integer> v2 = getMajorMinorVersion(s2);
 
-        if (v1.first == v2.first) {
+        if (Objects.equals(v1.first, v2.first)) {
             return Integer.compare(v1.second, v2.second);
         } else {
             return Integer.compare(v1.first, v2.first);