diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp index ac777d73ac..bd8fe7ceac 100644 --- a/Tethering/apex/Android.bp +++ b/Tethering/apex/Android.bp @@ -90,6 +90,8 @@ apex { compressible: true, androidManifest: "AndroidManifest.xml", + + compat_configs: ["connectivity-platform-compat-config"], } apex_key { diff --git a/framework/Android.bp b/framework/Android.bp index 3703df86cc..d7de43920d 100644 --- a/framework/Android.bp +++ b/framework/Android.bp @@ -92,6 +92,7 @@ java_defaults { "modules-utils-preconditions", ], libs: [ + "app-compat-annotations", "framework-connectivity-t.stubs.module_lib", "unsupportedappusage", ], @@ -152,6 +153,11 @@ java_sdk_library { ], } +platform_compat_config { + name: "connectivity-platform-compat-config", + src: ":framework-connectivity", +} + cc_library_shared { name: "libframework-connectivity-jni", min_sdk_version: "30", diff --git a/framework/src/android/net/LinkProperties.java b/framework/src/android/net/LinkProperties.java index 99f48b49c6..8782b33be5 100644 --- a/framework/src/android/net/LinkProperties.java +++ b/framework/src/android/net/LinkProperties.java @@ -19,12 +19,16 @@ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.app.compat.CompatChanges; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import com.android.internal.annotations.VisibleForTesting; import com.android.net.module.util.LinkPropertiesUtils; import java.net.Inet4Address; @@ -38,6 +42,7 @@ import java.util.Hashtable; import java.util.List; import java.util.Objects; import java.util.StringJoiner; +import java.util.stream.Collectors; /** * Describes the properties of a network link. @@ -52,6 +57,17 @@ import java.util.StringJoiner; * */ public final class LinkProperties implements Parcelable { + /** + * The {@link #getRoutes()} now can contain excluded as well as included routes. Use + * {@link RouteInfo#getType()} to determine route type. + * + * @hide + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S) // Switch to S_V2 when it is available. + @VisibleForTesting + public static final long EXCLUDED_ROUTES = 186082280; + // The interface described by the network link. @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mIfaceName; @@ -738,10 +754,25 @@ public final class LinkProperties implements Parcelable { /** * Returns all the {@link RouteInfo} set on this link. * + * Only unicast routes are returned for apps targeting Android S or below. + * * @return An unmodifiable {@link List} of {@link RouteInfo} for this link. */ public @NonNull List getRoutes() { - return Collections.unmodifiableList(mRoutes); + if (CompatChanges.isChangeEnabled(EXCLUDED_ROUTES)) { + return Collections.unmodifiableList(mRoutes); + } else { + return Collections.unmodifiableList(getUnicastRoutes()); + } + } + + /** + * Returns all the {@link RouteInfo} of type {@link RouteInfo#RTN_UNICAST} set on this link. + */ + private @NonNull List getUnicastRoutes() { + return mRoutes.stream() + .filter(route -> route.getType() == RouteInfo.RTN_UNICAST) + .collect(Collectors.toList()); } /** @@ -757,11 +788,14 @@ public final class LinkProperties implements Parcelable { /** * Returns all the routes on this link and all the links stacked above it. + * + * Only unicast routes are returned for apps targeting Android S or below. + * * @hide */ @SystemApi public @NonNull List getAllRoutes() { - List routes = new ArrayList<>(mRoutes); + final List routes = new ArrayList<>(getRoutes()); for (LinkProperties stacked: mStackedLinks.values()) { routes.addAll(stacked.getAllRoutes()); } diff --git a/tests/common/Android.bp b/tests/common/Android.bp index 7bb7cb562b..509e881a8b 100644 --- a/tests/common/Android.bp +++ b/tests/common/Android.bp @@ -36,6 +36,7 @@ java_library { "modules-utils-build", "net-tests-utils", "net-utils-framework-common", + "platform-compat-test-rules", "platform-test-annotations", ], libs: [ diff --git a/tests/common/java/android/net/LinkPropertiesTest.java b/tests/common/java/android/net/LinkPropertiesTest.java index 4d85a57e57..8fc636ab97 100644 --- a/tests/common/java/android/net/LinkPropertiesTest.java +++ b/tests/common/java/android/net/LinkPropertiesTest.java @@ -20,6 +20,7 @@ import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_UNICAST; import static android.net.RouteInfo.RTN_UNREACHABLE; +import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; import static com.android.testutils.ParcelUtils.parcelingRoundTrip; @@ -30,6 +31,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.compat.testing.PlatformCompatChangeRule; import android.net.LinkProperties.ProvisioningChange; import android.os.Build; import android.system.OsConstants; @@ -45,6 +47,9 @@ import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; +import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; +import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; + import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -65,6 +70,9 @@ public class LinkPropertiesTest { @Rule public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); + @Rule + public final PlatformCompatChangeRule compatChangeRule = new PlatformCompatChangeRule(); + private static final InetAddress ADDRV4 = address("75.208.6.1"); private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); private static final InetAddress DNS1 = address("75.208.7.1"); @@ -1254,6 +1262,7 @@ public class LinkPropertiesTest { } @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + @EnableCompatChanges({LinkProperties.EXCLUDED_ROUTES}) public void testRouteAddWithSameKey() throws Exception { LinkProperties lp = new LinkProperties(); lp.setInterfaceName("wlan0"); @@ -1268,4 +1277,36 @@ public class LinkPropertiesTest { lp.addRoute(new RouteInfo(v4, address("192.0.2.1"), "wlan0", RTN_THROW, 1460)); assertEquals(2, lp.getRoutes().size()); } + + @Test @IgnoreUpTo(SC_V2) + @EnableCompatChanges({LinkProperties.EXCLUDED_ROUTES}) + public void testExcludedRoutesEnabled() { + final LinkProperties lp = new LinkProperties(); + assertEquals(0, lp.getRoutes().size()); + + lp.addRoute(new RouteInfo(new IpPrefix(ADDRV4, 0), RTN_UNREACHABLE)); + assertEquals(1, lp.getRoutes().size()); + + lp.addRoute(new RouteInfo(new IpPrefix(ADDRV6, 0), RTN_THROW)); + assertEquals(2, lp.getRoutes().size()); + + lp.addRoute(new RouteInfo(GATEWAY1)); + assertEquals(3, lp.getRoutes().size()); + } + + @Test @IgnoreUpTo(SC_V2) + @DisableCompatChanges({LinkProperties.EXCLUDED_ROUTES}) + public void testExcludedRoutesDisabled() { + final LinkProperties lp = new LinkProperties(); + assertEquals(0, lp.getRoutes().size()); + + lp.addRoute(new RouteInfo(new IpPrefix(ADDRV4, 0), RTN_UNREACHABLE)); + assertEquals(0, lp.getRoutes().size()); + + lp.addRoute(new RouteInfo(new IpPrefix(ADDRV6, 5), RTN_THROW)); + assertEquals(0, lp.getRoutes().size()); + + lp.addRoute(new RouteInfo(new IpPrefix(ADDRV6, 2), RTN_UNICAST)); + assertEquals(1, lp.getRoutes().size()); + } }