Merge "Updates to NetworkFactory for the new NetworkAgent constructor"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index c3b8668..8f845bc 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -45,6 +45,7 @@
"//frameworks/opt/telephony",
"//packages/modules/NetworkStack",
"//packages/modules/CaptivePortalLogin",
+ "//frameworks/libs/net/common/tests:__subpackages__",
]
}
@@ -61,6 +62,7 @@
"//frameworks/opt/net/ike",
"//packages/modules/NetworkStack",
"//packages/modules/CaptivePortalLogin",
+ "//frameworks/libs/net/common/tests:__subpackages__",
],
}
diff --git a/staticlibs/src_frameworkcommon/android/net/util/LinkPropertiesUtils.java b/staticlibs/src_frameworkcommon/android/net/util/LinkPropertiesUtils.java
index 59d88ac..c50ca0b 100644
--- a/staticlibs/src_frameworkcommon/android/net/util/LinkPropertiesUtils.java
+++ b/staticlibs/src_frameworkcommon/android/net/util/LinkPropertiesUtils.java
@@ -26,8 +26,10 @@
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Objects;
+import java.util.function.Function;
/**
* Collection of link properties utilities.
@@ -65,6 +67,60 @@
}
/**
+ * Generic class to compare two lists of items of type {@code T} whose properties can change.
+ * The items to be compared must provide a way to calculate a corresponding key of type
+ * {@code K} such that if (and only if) an old and a new item have the same key, then the new
+ * item is an update of the old item. Both the old list and the new list may not contain more
+ * than one item with the same key, and may not contain any null items.
+ *
+ * @param <K> A class that represents the key of the items to be compared.
+ * @param <T> The class that represents the object to be compared.
+ */
+ public static class CompareOrUpdateResult<K, T> {
+ public final List<T> added = new ArrayList<>();
+ public final List<T> removed = new ArrayList<>();
+ public final List<T> updated = new ArrayList<>();
+
+ /**
+ * Compares two lists of items.
+ * @param oldItems the old list of items.
+ * @param newItems the new list of items.
+ * @param keyCalculator a {@link Function} that calculates an item's key.
+ */
+ public CompareOrUpdateResult(Collection<T> oldItems, Collection<T> newItems,
+ Function<T, K> keyCalculator) {
+ HashMap<K, T> updateTracker = new HashMap<>();
+
+ for (T oldItem : oldItems) {
+ updateTracker.put(keyCalculator.apply(oldItem), oldItem);
+ }
+
+ for (T newItem : newItems) {
+ T oldItem = updateTracker.remove(keyCalculator.apply(newItem));
+ if (oldItem != null) {
+ if (!oldItem.equals(newItem)) {
+ // Update of existing item.
+ updated.add(newItem);
+ }
+ } else {
+ // New item.
+ added.add(newItem);
+ }
+ }
+
+ removed.addAll(updateTracker.values());
+ }
+
+ @Override
+ public String toString() {
+ return "removed=[" + TextUtils.join(",", removed)
+ + "] added=[" + TextUtils.join(",", added)
+ + "] updated=[" + TextUtils.join(",", updated)
+ + "]";
+ }
+ }
+
+ /**
* Compares the addresses in {@code left} LinkProperties with {@code right}
* LinkProperties, examining only addresses on the base link.
*
diff --git a/staticlibs/tests/unit/Android.bp b/staticlibs/tests/unit/Android.bp
index 4a51a8c..fe363f5 100644
--- a/staticlibs/tests/unit/Android.bp
+++ b/staticlibs/tests/unit/Android.bp
@@ -6,9 +6,12 @@
name: "NetworkStaticLibTests",
certificate: "platform",
srcs: ["src/**/*.java","src/**/*.kt"],
+ jarjar_rules: "jarjar-rules.txt",
test_suites: ["device-tests"],
static_libs: [
"androidx.test.rules",
+ "net-utils-framework-common",
+ "net-utils-services-common",
],
libs: [
"android.test.runner",
diff --git a/staticlibs/tests/unit/jarjar-rules.txt b/staticlibs/tests/unit/jarjar-rules.txt
new file mode 100644
index 0000000..dbb3974
--- /dev/null
+++ b/staticlibs/tests/unit/jarjar-rules.txt
@@ -0,0 +1,4 @@
+# Ensure that the tests can directly use the version of classes from the library. Otherwise, they
+# will use whatever version is currently in the bootclasspath on the device running the test.
+# These rules must match the jarjar rules used to build the library.
+rule android.net.util.** com.android.net.module.util.@1
diff --git a/staticlibs/tests/unit/src/android/net/util/LinkPropertiesUtilsTest.java b/staticlibs/tests/unit/src/android/net/util/LinkPropertiesUtilsTest.java
index 6e06ee8..e2cde34 100644
--- a/staticlibs/tests/unit/src/android/net/util/LinkPropertiesUtilsTest.java
+++ b/staticlibs/tests/unit/src/android/net/util/LinkPropertiesUtilsTest.java
@@ -26,6 +26,7 @@
import android.net.LinkProperties;
import android.net.ProxyInfo;
import android.net.RouteInfo;
+import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult;
import android.net.util.LinkPropertiesUtils.CompareResult;
import androidx.test.runner.AndroidJUnit4;
@@ -34,6 +35,11 @@
import org.junit.runner.RunWith;
import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.function.Function;
@RunWith(AndroidJUnit4.class)
public final class LinkPropertiesUtilsTest {
@@ -185,4 +191,58 @@
assertEquals(linkAddr1, results.removed.get(0));
assertEquals(linkAddr2, results.added.get(0));
}
-}
+
+ private void assertSameElements(List<String> expected, List<String> actual) {
+ HashSet<String> expectedSet = new HashSet(expected);
+ assertEquals("expected list contains duplicates", expectedSet.size(), expected.size());
+ HashSet<String> actualSet = new HashSet(actual);
+ assertEquals("actual list contains duplicates", actualSet.size(), actual.size());
+ assertEquals(expectedSet, actualSet);
+ }
+
+ private void assertCompareOrUpdateResult(CompareOrUpdateResult result,
+ List<String> expectedAdded, List<String> expectedRemoved,
+ List<String> expectedUpdated) {
+ assertSameElements(expectedAdded, result.added);
+ assertSameElements(expectedRemoved, result.removed);
+ assertSameElements(expectedUpdated, result.updated);
+ }
+
+ private List<String> strArray(String... strs) {
+ return Arrays.asList(strs);
+ }
+
+ @Test
+ public void testCompareOrUpdateResult() {
+ // As the item type, use a simple string. An item is defined to be an update of another item
+ // if the string starts with the same alphabetical characters.
+ // Extracting the key from the object is just a regexp.
+ Function<String, String> extractPrefix = (s) -> s.replaceFirst("^([a-z]+).*", "$1");
+ assertEquals("goodbye", extractPrefix.apply("goodbye1234"));
+
+ List<String> oldItems = strArray("hello123", "goodbye5678", "howareyou669");
+ List<String> newItems = strArray("hello123", "goodbye000", "verywell");
+
+ final List<String> emptyList = new ArrayList<>();
+
+ // Items -> empty: everything removed.
+ CompareOrUpdateResult<String, String> result =
+ new CompareOrUpdateResult<String, String>(oldItems, emptyList, extractPrefix);
+ assertCompareOrUpdateResult(result,
+ emptyList, strArray("hello123", "howareyou669", "goodbye5678"), emptyList);
+
+ // Empty -> items: everything added.
+ result = new CompareOrUpdateResult<String, String>(emptyList, newItems, extractPrefix);
+ assertCompareOrUpdateResult(result,
+ strArray("hello123", "goodbye000", "verywell"), emptyList, emptyList);
+
+ // Empty -> empty: no change.
+ result = new CompareOrUpdateResult<String, String>(newItems, newItems, extractPrefix);
+ assertCompareOrUpdateResult(result, emptyList, emptyList, emptyList);
+
+ // Added, removed, updated at the same time.
+ result = new CompareOrUpdateResult<>(oldItems, newItems, extractPrefix);
+ assertCompareOrUpdateResult(result,
+ strArray("verywell"), strArray("howareyou669"), strArray("goodbye000"));
+ }
+}
\ No newline at end of file