diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index e7184eddc4..2032db5e86 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -540,20 +540,94 @@ public final class LinkProperties implements Parcelable { } /** - * Returns true if this link has an IPv6 address. + * Returns true if this link has a global preferred IPv6 address. * - * @return {@code true} if there is an IPv6 address, {@code false} otherwise. + * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise. * @hide */ - public boolean hasIPv6Address() { + public boolean hasGlobalIPv6Address() { for (LinkAddress address : mLinkAddresses) { - if (address.getAddress() instanceof Inet6Address) { + if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) { return true; } } return false; } + /** + * Returns true if this link has an IPv4 default route. + * + * @return {@code true} if there is an IPv4 default route, {@code false} otherwise. + * @hide + */ + public boolean hasIPv4DefaultRoute() { + for (RouteInfo r : mRoutes) { + if (r.isIPv4Default()) { + return true; + } + } + return false; + } + + /** + * Returns true if this link has an IPv6 default route. + * + * @return {@code true} if there is an IPv6 default route, {@code false} otherwise. + * @hide + */ + public boolean hasIPv6DefaultRoute() { + for (RouteInfo r : mRoutes) { + if (r.isIPv6Default()) { + return true; + } + } + return false; + } + + /** + * Returns true if this link has an IPv4 DNS server. + * + * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise. + * @hide + */ + public boolean hasIPv4DnsServer() { + for (InetAddress ia : mDnses) { + if (ia instanceof Inet4Address) { + return true; + } + } + return false; + } + + /** + * Returns true if this link has an IPv6 DNS server. + * + * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise. + * @hide + */ + public boolean hasIPv6DnsServer() { + for (InetAddress ia : mDnses) { + if (ia instanceof Inet6Address) { + return true; + } + } + return false; + } + + /** + * Returns true if this link is provisioned for global connectivity. For IPv6, this requires an + * IP address, default route, and DNS server. For IPv4, this requires only an IPv4 address, + * because WifiStateMachine accepts static configurations that only specify an address but not + * DNS servers or a default route. + * + * @return {@code true} if the link is provisioned, {@code false} otherwise. + * @hide + */ + public boolean isProvisioned() { + return (hasIPv4Address() || + (hasGlobalIPv6Address() && hasIPv6DefaultRoute() && hasIPv6DnsServer())); + } + /** * Compares this {@code LinkProperties} interface name against the target * diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java index 9646510ba8..4015b3d65b 100644 --- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java +++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java @@ -38,6 +38,7 @@ public class LinkPropertiesTest extends TestCase { private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32); private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128); + private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64"); public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) { // Check implementation of equals(), element by element. @@ -357,7 +358,7 @@ public class LinkPropertiesTest extends TestCase { // No addresses. assertFalse(lp.hasIPv4Address()); - assertFalse(lp.hasIPv6Address()); + assertFalse(lp.hasGlobalIPv6Address()); // Addresses on stacked links don't count. LinkProperties stacked = new LinkProperties(); @@ -366,12 +367,12 @@ public class LinkPropertiesTest extends TestCase { stacked.addLinkAddress(LINKADDRV4); stacked.addLinkAddress(LINKADDRV6); assertTrue(stacked.hasIPv4Address()); - assertTrue(stacked.hasIPv6Address()); + assertTrue(stacked.hasGlobalIPv6Address()); assertFalse(lp.hasIPv4Address()); - assertFalse(lp.hasIPv6Address()); + assertFalse(lp.hasGlobalIPv6Address()); lp.removeStackedLink(stacked); assertFalse(lp.hasIPv4Address()); - assertFalse(lp.hasIPv6Address()); + assertFalse(lp.hasGlobalIPv6Address()); // Addresses on the base link. // Check the return values of hasIPvXAddress and ensure the add/remove methods return true @@ -380,19 +381,29 @@ public class LinkPropertiesTest extends TestCase { assertTrue(lp.addLinkAddress(LINKADDRV6)); assertEquals(1, lp.getLinkAddresses().size()); assertFalse(lp.hasIPv4Address()); - assertTrue(lp.hasIPv6Address()); + assertTrue(lp.hasGlobalIPv6Address()); assertTrue(lp.removeLinkAddress(LINKADDRV6)); assertEquals(0, lp.getLinkAddresses().size()); - assertTrue(lp.addLinkAddress(LINKADDRV4)); - assertEquals(1, lp.getLinkAddresses().size()); - assertTrue(lp.hasIPv4Address()); - assertFalse(lp.hasIPv6Address()); - assertTrue(lp.addLinkAddress(LINKADDRV6)); + assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL)); + assertEquals(1, lp.getLinkAddresses().size()); + assertFalse(lp.hasGlobalIPv6Address()); + + assertTrue(lp.addLinkAddress(LINKADDRV4)); assertEquals(2, lp.getLinkAddresses().size()); assertTrue(lp.hasIPv4Address()); - assertTrue(lp.hasIPv6Address()); + assertFalse(lp.hasGlobalIPv6Address()); + + assertTrue(lp.addLinkAddress(LINKADDRV6)); + assertEquals(3, lp.getLinkAddresses().size()); + assertTrue(lp.hasIPv4Address()); + assertTrue(lp.hasGlobalIPv6Address()); + + assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL)); + assertEquals(2, lp.getLinkAddresses().size()); + assertTrue(lp.hasIPv4Address()); + assertTrue(lp.hasGlobalIPv6Address()); // Adding an address twice has no effect. // Removing an address that's not present has no effect. diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 00bda06146..2f5524e622 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -4713,7 +4713,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { LinkProperties lp = mCs.getLinkPropertiesForTypeInternal( ConnectivityManager.TYPE_MOBILE_HIPRI); boolean linkHasIpv4 = lp.hasIPv4Address(); - boolean linkHasIpv6 = lp.hasIPv6Address(); + boolean linkHasIpv6 = lp.hasGlobalIPv6Address(); log("isMobileOk: linkHasIpv4=" + linkHasIpv4 + " linkHasIpv6=" + linkHasIpv6);