summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2013-03-07 10:59:25 -0800
committerLorenzo Colitti <lorenzo@google.com>2013-03-15 14:35:32 +0900
commit419a4ce9e461177d75eca5fd71fc8c275969e479 (patch)
tree338655dfc2c2ecdf49e27010f9d89ae101ebfa67 /core
parent41c9c8e5847b0d252673e9cceda0c4bc8c843fa1 (diff)
downloadframeworks_base-419a4ce9e461177d75eca5fd71fc8c275969e479.zip
frameworks_base-419a4ce9e461177d75eca5fd71fc8c275969e479.tar.gz
frameworks_base-419a4ce9e461177d75eca5fd71fc8c275969e479.tar.bz2
Add stacked interfaces to LinkProperties.
Bug: 8276725 Change-Id: I2f592d4c690e9af0459ae742ab16107a10d89353
Diffstat (limited to 'core')
-rw-r--r--core/java/android/net/LinkProperties.java139
-rw-r--r--core/tests/coretests/src/android/net/LinkPropertiesTest.java26
2 files changed, 159 insertions, 6 deletions
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 9292e5f..833549f 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -23,10 +23,13 @@ import android.text.TextUtils;
import android.util.Log;
import java.net.InetAddress;
+import java.net.Inet4Address;
+
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Hashtable;
/**
* Describes the properties of a network link.
@@ -48,10 +51,15 @@ import java.util.Collections;
* don't care which is used. The gateways will be
* selected based on the destination address and the
* source address has no relavence.
+ *
+ * Links can also be stacked on top of each other.
+ * This can be used, for example, to represent a tunnel
+ * interface that runs on top of a physical interface.
+ *
* @hide
*/
public class LinkProperties implements Parcelable {
-
+ // The interface described by the network link.
private String mIfaceName;
private Collection<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
private Collection<InetAddress> mDnses = new ArrayList<InetAddress>();
@@ -60,6 +68,11 @@ public class LinkProperties implements Parcelable {
private ProxyProperties mHttpProxy;
public boolean mLogMe;
+ // Stores the properties of links that are "stacked" above this link.
+ // Indexed by interface name to allow modification and to prevent duplicates being added.
+ private Hashtable<String, LinkProperties> mStackedLinks =
+ new Hashtable<String, LinkProperties>();
+
public static class CompareResult<T> {
public Collection<T> removed = new ArrayList<T>();
public Collection<T> added = new ArrayList<T>();
@@ -90,6 +103,9 @@ public class LinkProperties implements Parcelable {
for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
mHttpProxy = (source.getHttpProxy() == null) ?
null : new ProxyProperties(source.getHttpProxy());
+ for (LinkProperties l: source.mStackedLinks.values()) {
+ addStackedLink(l);
+ }
}
}
@@ -165,10 +181,25 @@ public class LinkProperties implements Parcelable {
}
}
+ /**
+ * Returns all the routes on this link.
+ */
public Collection<RouteInfo> getRoutes() {
return Collections.unmodifiableCollection(mRoutes);
}
+ /**
+ * Returns all the routes on this link and all the links stacked above it.
+ */
+ public Collection<RouteInfo> getAllRoutes() {
+ Collection<RouteInfo> routes = new ArrayList();
+ routes.addAll(mRoutes);
+ for (LinkProperties stacked: mStackedLinks.values()) {
+ routes.addAll(stacked.getAllRoutes());
+ }
+ return Collections.unmodifiableCollection(routes);
+ }
+
public void setHttpProxy(ProxyProperties proxy) {
mHttpProxy = proxy;
}
@@ -176,6 +207,46 @@ public class LinkProperties implements Parcelable {
return mHttpProxy;
}
+ /**
+ * Adds a stacked link.
+ *
+ * If there is already a stacked link with the same interfacename as link,
+ * that link is replaced with link. Otherwise, link is added to the list
+ * of stacked links. If link is null, nothing changes.
+ *
+ * @param link The link to add.
+ */
+ public void addStackedLink(LinkProperties link) {
+ if (link != null && link.getInterfaceName() != null) {
+ mStackedLinks.put(link.getInterfaceName(), link);
+ }
+ }
+
+ /**
+ * Removes a stacked link.
+ *
+ * If there a stacked link with the same interfacename as link, it is
+ * removed. Otherwise, nothing changes.
+ *
+ * @param link The link to add.
+ */
+ public void removeStackedLink(LinkProperties link) {
+ if (link != null && link.getInterfaceName() != null) {
+ mStackedLinks.remove(link.getInterfaceName());
+ }
+ }
+
+ /**
+ * Returns all the links stacked on top of this link.
+ */
+ public Collection<LinkProperties> getStackedLinks() {
+ Collection<LinkProperties> stacked = new ArrayList<LinkProperties>();
+ for (LinkProperties link : mStackedLinks.values()) {
+ stacked.add(new LinkProperties(link));
+ }
+ return Collections.unmodifiableCollection(stacked);
+ }
+
public void clear() {
if (mLogMe) {
Log.d("LinkProperties", "clear from " + mIfaceName);
@@ -190,6 +261,7 @@ public class LinkProperties implements Parcelable {
mDomains = null;
mRoutes.clear();
mHttpProxy = null;
+ mStackedLinks.clear();
}
/**
@@ -219,7 +291,29 @@ public class LinkProperties implements Parcelable {
routes += "] ";
String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
- return ifaceName + linkAddresses + routes + dns + domainName + proxy;
+ String stacked = "";
+ if (mStackedLinks.values().size() > 0) {
+ stacked += " Stacked: [";
+ for (LinkProperties link: mStackedLinks.values()) {
+ stacked += " [" + link.toString() + " ],";
+ }
+ stacked += "] ";
+ }
+ return ifaceName + linkAddresses + routes + dns + domainName + proxy + stacked;
+ }
+
+ /**
+ * Returns true if this link has an IPv4 address.
+ *
+ * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
+ */
+ public boolean hasIPv4Address() {
+ for (LinkAddress address : mLinkAddresses) {
+ if (address.getAddress() instanceof Inet4Address) {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -286,6 +380,26 @@ public class LinkProperties implements Parcelable {
getHttpProxy().equals(target.getHttpProxy());
}
+ /**
+ * Compares this {@code LinkProperties} stacked links against the target
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ */
+ public boolean isIdenticalStackedLinks(LinkProperties target) {
+ if (!mStackedLinks.keys().equals(target.mStackedLinks.keys())) {
+ return false;
+ }
+ for (LinkProperties stacked : mStackedLinks.values()) {
+ // Hashtable values can never be null.
+ String iface = stacked.getInterfaceName();
+ if (!stacked.equals(target.mStackedLinks.get(iface))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@Override
/**
* Compares this {@code LinkProperties} instance against the target
@@ -298,6 +412,10 @@ public class LinkProperties implements Parcelable {
* 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
* 2. Worst case performance is O(n^2).
*
+ * This method does not check that stacked interfaces are equal, because
+ * stacked interfaces are not so much a property of the link as a
+ * description of connections between links.
+ *
* @param obj the object to be tested for equality.
* @return {@code true} if both objects are equal, {@code false} otherwise.
*/
@@ -312,7 +430,8 @@ public class LinkProperties implements Parcelable {
isIdenticalAddresses(target) &&
isIdenticalDnses(target) &&
isIdenticalRoutes(target) &&
- isIdenticalHttpProxy(target);
+ isIdenticalHttpProxy(target) &&
+ isIdenticalStackedLinks(target);
}
/**
@@ -394,10 +513,10 @@ public class LinkProperties implements Parcelable {
*/
CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
- result.removed = new ArrayList<RouteInfo>(mRoutes);
+ result.removed = getAllRoutes();
result.added.clear();
if (target != null) {
- for (RouteInfo r : target.getRoutes()) {
+ for (RouteInfo r : target.getAllRoutes()) {
if (! result.removed.remove(r)) {
result.added.add(r);
}
@@ -419,7 +538,8 @@ public class LinkProperties implements Parcelable {
+ mDnses.size() * 37
+ ((null == mDomains) ? 0 : mDomains.hashCode())
+ mRoutes.size() * 41
- + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode()));
+ + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
+ + mStackedLinks.hashCode() * 47);
}
/**
@@ -449,6 +569,8 @@ public class LinkProperties implements Parcelable {
} else {
dest.writeByte((byte)0);
}
+ ArrayList<LinkProperties> stackedLinks = new ArrayList(mStackedLinks.values());
+ dest.writeList(stackedLinks);
}
/**
@@ -481,6 +603,11 @@ public class LinkProperties implements Parcelable {
if (in.readByte() == 1) {
netProp.setHttpProxy((ProxyProperties)in.readParcelable(null));
}
+ ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
+ in.readList(stackedLinks, LinkProperties.class.getClassLoader());
+ for (LinkProperties stackedLink: stackedLinks) {
+ netProp.addStackedLink(stackedLink);
+ }
return netProp;
}
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index fffaa00..c746e52 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -22,6 +22,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
import java.net.InetAddress;
+import java.util.ArrayList;
public class LinkPropertiesTest extends TestCase {
private static String ADDRV4 = "75.208.6.1";
@@ -255,5 +256,30 @@ public class LinkPropertiesTest extends TestCase {
assertAllRoutesHaveInterface("p2p0", lp2);
assertEquals(3, lp.compareRoutes(lp2).added.size());
assertEquals(3, lp.compareRoutes(lp2).removed.size());
+
+ @SmallTest
+ public void testStackedInterfaces() {
+ LinkProperties rmnet0 = new LinkProperties();
+ rmnet0.setInterfaceName("rmnet0");
+
+ LinkProperties clat4 = new LinkProperties();
+ clat4.setInterfaceName("clat4");
+
+ assertEquals(0, rmnet0.getStackedLinks().size());
+ rmnet0.addStackedLink(clat4);
+ assertEquals(1, rmnet0.getStackedLinks().size());
+ rmnet0.addStackedLink(clat4);
+ assertEquals(1, rmnet0.getStackedLinks().size());
+ assertEquals(0, clat4.getStackedLinks().size());
+
+ // Modify an item in the returned collection to see what happens.
+ for (LinkProperties link : rmnet0.getStackedLinks()) {
+ if (link.getInterfaceName().equals("clat4")) {
+ link.setInterfaceName("newname");
+ }
+ }
+ for (LinkProperties link : rmnet0.getStackedLinks()) {
+ assertFalse("newname".equals(link.getInterfaceName()));
+ }
}
}