diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index f527f77ddd..2c9fb23e07 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -70,8 +70,23 @@ public final class LinkProperties implements Parcelable { * @hide */ public static class CompareResult { - public List removed = new ArrayList(); - public List added = new ArrayList(); + public final List removed = new ArrayList(); + public final List added = new ArrayList(); + + public CompareResult() {} + + public CompareResult(Collection oldItems, Collection newItems) { + if (oldItems != null) { + removed.addAll(oldItems); + } + if (newItems != null) { + for (T newItem : newItems) { + if (!removed.remove(newItem)) { + added.add(newItem); + } + } + } + } @Override public String toString() { @@ -1000,17 +1015,8 @@ public final class LinkProperties implements Parcelable { * are in target but not in mLinkAddresses are placed in the * addedAddresses. */ - CompareResult result = new CompareResult(); - result.removed = new ArrayList(mLinkAddresses); - result.added.clear(); - if (target != null) { - for (LinkAddress newAddress : target.getLinkAddresses()) { - if (! result.removed.remove(newAddress)) { - result.added.add(newAddress); - } - } - } - return result; + return new CompareResult<>(mLinkAddresses, + target != null ? target.getLinkAddresses() : null); } /** @@ -1029,18 +1035,7 @@ public final class LinkProperties implements Parcelable { * are in target but not in mDnses are placed in the * addedAddresses. */ - CompareResult result = new CompareResult(); - - result.removed = new ArrayList(mDnses); - result.added.clear(); - if (target != null) { - for (InetAddress newAddress : target.getDnsServers()) { - if (! result.removed.remove(newAddress)) { - result.added.add(newAddress); - } - } - } - return result; + return new CompareResult<>(mDnses, target != null ? target.getDnsServers() : null); } /** @@ -1058,18 +1053,7 @@ public final class LinkProperties implements Parcelable { * leaving the routes that are different. And route address which * are in target but not in mRoutes are placed in added. */ - CompareResult result = new CompareResult(); - - result.removed = getAllRoutes(); - result.added.clear(); - if (target != null) { - for (RouteInfo r : target.getAllRoutes()) { - if (! result.removed.remove(r)) { - result.added.add(r); - } - } - } - return result; + return new CompareResult<>(getAllRoutes(), target != null ? target.getAllRoutes() : null); } /** @@ -1087,18 +1071,8 @@ public final class LinkProperties implements Parcelable { * leaving the interface names that are different. And interface names which * are in target but not in this are placed in added. */ - CompareResult result = new CompareResult(); - - result.removed = getAllInterfaceNames(); - result.added.clear(); - if (target != null) { - for (String r : target.getAllInterfaceNames()) { - if (! result.removed.remove(r)) { - result.added.add(r); - } - } - } - return result; + return new CompareResult<>(getAllInterfaceNames(), + target != null ? target.getAllInterfaceNames() : null); } diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java index 9686dd9e57..bc2b9a632b 100644 --- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java +++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java @@ -19,6 +19,7 @@ package android.net; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; +import android.net.LinkProperties.CompareResult; import android.net.LinkProperties.ProvisioningChange; import android.net.RouteInfo; import android.system.OsConstants; @@ -29,9 +30,11 @@ import android.util.ArraySet; import junit.framework.TestCase; import java.net.InetAddress; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Set; @@ -747,6 +750,27 @@ public class LinkPropertiesTest extends TestCase { } + @SmallTest + public void testCompareResult() { + // Either adding or removing items + testCompareResult(Arrays.asList(1), Arrays.asList(1, 2, 3, 4), + Arrays.asList(2, 3, 4), new ArrayList<>()); + testCompareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4), + new ArrayList<>(), Arrays.asList(3, 4)); + + + // adding and removing items at the same time + testCompareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5), + Arrays.asList(1), Arrays.asList(5)); + testCompareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), + Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6)); + + // null cases + testCompareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>()); + testCompareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3)); + testCompareResult(null, null, new ArrayList<>(), new ArrayList<>()); + } + private void assertEqualRoutes(Collection expected, Collection actual) { Set expectedSet = new ArraySet<>(expected); Set actualSet = new ArraySet<>(actual); @@ -755,4 +779,11 @@ public class LinkPropertiesTest extends TestCase { assertEquals(expectedSet, actualSet); } + + private void testCompareResult(List oldItems, List newItems, List expectAdded, + List expectRemoved) { + CompareResult result = new CompareResult<>(newItems, oldItems); + assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added)); + assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed))); + } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 69350b26c7..31fc874db2 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -4435,12 +4435,9 @@ public class ConnectivityService extends IConnectivityManager.Stub private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, NetworkCapabilities caps) { - CompareResult interfaceDiff = new CompareResult(); - if (oldLp != null) { - interfaceDiff = oldLp.compareAllInterfaceNames(newLp); - } else if (newLp != null) { - interfaceDiff.added = newLp.getAllInterfaceNames(); - } + CompareResult interfaceDiff = new CompareResult( + oldLp != null ? oldLp.getAllInterfaceNames() : null, + newLp != null ? newLp.getAllInterfaceNames() : null); for (String iface : interfaceDiff.added) { try { if (DBG) log("Adding iface " + iface + " to network " + netId); @@ -4466,12 +4463,10 @@ public class ConnectivityService extends IConnectivityManager.Stub * @return true if routes changed between oldLp and newLp */ private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) { - CompareResult routeDiff = new CompareResult(); - if (oldLp != null) { - routeDiff = oldLp.compareAllRoutes(newLp); - } else if (newLp != null) { - routeDiff.added = newLp.getAllRoutes(); - } + // Compare the route diff to determine which routes should be added and removed. + CompareResult routeDiff = new CompareResult( + oldLp != null ? oldLp.getAllRoutes() : null, + newLp != null ? newLp.getAllRoutes() : null); // add routes before removing old in case it helps with continuous connectivity