Merge "Add the tethering type to TetheringEventCallback methods" into sc-dev
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 5be3933..dcdf693 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -23,9 +23,10 @@
     compile_multilib: "both",
     updatable: true,
     min_sdk_version: "30",
+    bootclasspath_fragments: [
+        "com.android.tethering-bootclasspath-fragment",
+    ],
     java_libs: [
-        "framework-connectivity",
-        "framework-tethering",
         "service-connectivity",
     ],
     multilib: {
@@ -61,6 +62,16 @@
     certificate: "com.android.tethering",
 }
 
+// Encapsulate the contributions made by the com.android.tethering to the bootclasspath.
+bootclasspath_fragment {
+    name: "com.android.tethering-bootclasspath-fragment",
+    contents: [
+        "framework-connectivity",
+        "framework-tethering",
+    ],
+    apex_available: ["com.android.tethering"],
+}
+
 override_apex {
     name: "com.android.tethering.inprocess",
     base: "com.android.tethering",
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index 413b0cb..2beeeb8 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -58,6 +58,8 @@
 
     private static final String[] EMPTY_STRING_ARRAY = new String[0];
 
+    private static final String TETHERING_MODULE_NAME = "com.android.tethering";
+
     // Default ranges used for the legacy DHCP server.
     // USB is  192.168.42.1 and 255.255.255.0
     // Wifi is 192.168.43.1 and 255.255.255.0
@@ -473,7 +475,8 @@
 
     @VisibleForTesting
     protected boolean isFeatureEnabled(Context ctx, String featureVersionFlag) {
-        return DeviceConfigUtils.isFeatureEnabled(ctx, NAMESPACE_CONNECTIVITY, featureVersionFlag);
+        return DeviceConfigUtils.isFeatureEnabled(ctx, NAMESPACE_CONNECTIVITY, featureVersionFlag,
+                TETHERING_MODULE_NAME, false /* defaultEnabled */);
     }
 
     private Resources getResources(Context ctx, int subId) {
diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
index 1a97566..bca4456 100644
--- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
@@ -32,6 +32,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
@@ -309,6 +310,43 @@
                 request.networkCapabilities.satisfiedByNetworkCapabilities(nc));
     }
 
+    private static Set<Range<Integer>> uidRangesForUid(int uid) {
+        final Range<Integer> range = new Range<>(uid, uid);
+        return Set.of(range);
+    }
+
+    @Test
+    public void testSetIncludeOtherUidNetworks() throws Exception {
+        assumeTrue(TestUtils.shouldTestSApis());
+        final NetworkRequestShim shim = NetworkRequestShimImpl.newInstance();
+
+        final NetworkRequest.Builder builder = new NetworkRequest.Builder();
+        // NetworkRequests have NET_CAPABILITY_NOT_VCN_MANAGED by default.
+        builder.removeCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED);
+        shim.setIncludeOtherUidNetworks(builder, false);
+        final NetworkRequest request = builder.build();
+
+        final NetworkRequest.Builder otherUidsBuilder = new NetworkRequest.Builder();
+        otherUidsBuilder.removeCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED);
+        shim.setIncludeOtherUidNetworks(otherUidsBuilder, true);
+        final NetworkRequest otherUidsRequest = otherUidsBuilder.build();
+
+        assertNotEquals(Process.SYSTEM_UID, Process.myUid());
+        final NetworkCapabilities ncWithMyUid = new NetworkCapabilities()
+                .setUids(uidRangesForUid(Process.myUid()));
+        final NetworkCapabilities ncWithOtherUid = new NetworkCapabilities()
+                .setUids(uidRangesForUid(Process.SYSTEM_UID));
+
+        assertTrue(request + " should be satisfied by " + ncWithMyUid,
+                request.canBeSatisfiedBy(ncWithMyUid));
+        assertTrue(otherUidsRequest + " should be satisfied by " + ncWithMyUid,
+                otherUidsRequest.canBeSatisfiedBy(ncWithMyUid));
+        assertFalse(request + " should not be satisfied by " +  ncWithOtherUid,
+                request.canBeSatisfiedBy(ncWithOtherUid));
+        assertTrue(otherUidsRequest + " should be satisfied by " + ncWithOtherUid,
+                otherUidsRequest.canBeSatisfiedBy(ncWithOtherUid));
+    }
+
     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testRequestorUid() {
         final NetworkCapabilities nc = new NetworkCapabilities();
@@ -327,7 +365,7 @@
     // TODO: 1. Refactor test cases with helper method.
     //       2. Test capability that does not yet exist.
     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
-    public void testBypassingVcnForNonInternetRequest() {
+    public void testBypassingVcn() {
         // Make an empty request. Verify the NOT_VCN_MANAGED is added.
         final NetworkRequest emptyRequest = new NetworkRequest.Builder().build();
         assertTrue(emptyRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
@@ -360,12 +398,12 @@
                 .addCapability(NET_CAPABILITY_NOT_ROAMING).build();
         assertTrue(notRoamRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
 
-        // Make a internet request. Verify the NOT_VCN_MANAGED is added.
+        // Make an internet request. Verify the NOT_VCN_MANAGED is added.
         final NetworkRequest internetRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_INTERNET).build();
         assertTrue(internetRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
 
-        // Make a internet request which explicitly removed NOT_VCN_MANAGED.
+        // Make an internet request which explicitly removed NOT_VCN_MANAGED.
         // Verify the NOT_VCN_MANAGED is removed.
         final NetworkRequest internetRemoveNotVcnRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_INTERNET)
@@ -398,6 +436,14 @@
         final NetworkRequest dunRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_DUN).build();
         assertTrue(dunRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
+
+        // Make an internet request but with NetworkSpecifier. Verify the NOT_VCN_MANAGED is not
+        // added.
+        final NetworkRequest internetWithSpecifierRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI).addCapability(NET_CAPABILITY_INTERNET)
+                .setNetworkSpecifier(makeTestWifiSpecifier()).build();
+        assertFalse(internetWithSpecifierRequest.hasCapability(
+                ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
     }
 
     private void verifyEqualRequestBuilt(NetworkRequest orig) {
@@ -424,17 +470,20 @@
                 .setSignalStrength(-99).build();
         verifyEqualRequestBuilt(requestCellMms);
 
-        final WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL))
-                .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS)
-                .build();
         final NetworkRequest requestWifi = builder
                 .addTransportType(TRANSPORT_WIFI)
                 .removeTransportType(TRANSPORT_CELLULAR)
                 .addCapability(NET_CAPABILITY_INTERNET)
                 .removeCapability(NET_CAPABILITY_MMS)
-                .setNetworkSpecifier(specifier)
+                .setNetworkSpecifier(makeTestWifiSpecifier())
                 .setSignalStrength(-33).build();
         verifyEqualRequestBuilt(requestWifi);
     }
+
+    private WifiNetworkSpecifier makeTestWifiSpecifier() {
+        return new WifiNetworkSpecifier.Builder()
+                .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL))
+                .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS)
+                .build();
+    }
 }