Merge "Add checks for CT public key against allowlist" into main
diff --git a/bpf/headers/include/bpf_helpers.h b/bpf/headers/include/bpf_helpers.h
index 6a0e5a8..9d6b6f6 100644
--- a/bpf/headers/include/bpf_helpers.h
+++ b/bpf/headers/include/bpf_helpers.h
@@ -46,12 +46,12 @@
 #define BPFLOADER_U_QPR2_VERSION 41u
 #define BPFLOADER_PLATFORM_VERSION BPFLOADER_U_QPR2_VERSION
 
-// Android Mainline - this bpfloader should eventually go back to T (or even S)
+// Android Mainline BpfLoader when running on Android S (sdk=31)
 // Note: this value (and the following +1u's) are hardcoded in NetBpfLoad.cpp
-#define BPFLOADER_MAINLINE_VERSION 42u
+#define BPFLOADER_MAINLINE_S_VERSION 42u
 
 // Android Mainline BpfLoader when running on Android T (sdk=33)
-#define BPFLOADER_MAINLINE_T_VERSION (BPFLOADER_MAINLINE_VERSION + 1u)
+#define BPFLOADER_MAINLINE_T_VERSION (BPFLOADER_MAINLINE_S_VERSION + 1u)
 
 // Android Mainline BpfLoader when running on Android U (sdk=34)
 #define BPFLOADER_MAINLINE_U_VERSION (BPFLOADER_MAINLINE_T_VERSION + 1u)
@@ -112,7 +112,7 @@
     unsigned int _bpfloader_max_ver SECTION("bpfloader_max_ver") = BPFLOADER_MAX_VER;              \
     size_t _size_of_bpf_map_def SECTION("size_of_bpf_map_def") = sizeof(struct bpf_map_def);       \
     size_t _size_of_bpf_prog_def SECTION("size_of_bpf_prog_def") = sizeof(struct bpf_prog_def);    \
-    unsigned _btf_min_bpfloader_ver SECTION("btf_min_bpfloader_ver") = BPFLOADER_MAINLINE_VERSION; \
+    unsigned _btf_min_bpfloader_ver SECTION("btf_min_bpfloader_ver") = BPFLOADER_MAINLINE_S_VERSION; \
     unsigned _btf_user_min_bpfloader_ver SECTION("btf_user_min_bpfloader_ver") = 0xFFFFFFFFu;      \
     char _license[] SECTION("license") = (NAME)
 
diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp
index 9486e75..9c62e74 100644
--- a/bpf/loader/NetBpfLoad.cpp
+++ b/bpf/loader/NetBpfLoad.cpp
@@ -60,7 +60,7 @@
 #include "bpf_map_def.h"
 
 // The following matches bpf_helpers.h, which is only for inclusion in bpf code
-#define BPFLOADER_MAINLINE_VERSION 42u
+#define BPFLOADER_MAINLINE_S_VERSION 42u
 #define BPFLOADER_MAINLINE_25Q2_VERSION 47u
 
 using android::base::EndsWith;
@@ -1187,7 +1187,7 @@
     ret = readCodeSections(elfFile, cs);
     // BPF .o's with no programs are only supported by mainline netbpfload,
     // make sure .o's targeting non-mainline (ie. S) bpfloader don't show up.
-    if (ret == -ENOENT && bpfLoaderMinVer >= BPFLOADER_MAINLINE_VERSION)
+    if (ret == -ENOENT && bpfLoaderMinVer >= BPFLOADER_MAINLINE_S_VERSION)
         return 0;
     if (ret) {
         ALOGE("Couldn't read all code sections in %s", elfPath);
@@ -1422,7 +1422,7 @@
     const bool has_platform_netbpfload_rc = exists("/system/etc/init/netbpfload.rc");
 
     // Version of Network BpfLoader depends on the Android OS version
-    unsigned int bpfloader_ver = BPFLOADER_MAINLINE_VERSION;  // [42u]
+    unsigned int bpfloader_ver = BPFLOADER_MAINLINE_S_VERSION;  // [42u]
     if (isAtLeastT) ++bpfloader_ver;     // [43] BPFLOADER_MAINLINE_T_VERSION
     if (isAtLeastU) ++bpfloader_ver;     // [44] BPFLOADER_MAINLINE_U_VERSION
     if (runningAsRoot) ++bpfloader_ver;  // [45] BPFLOADER_MAINLINE_U_QPR3_VERSION
diff --git a/framework/src/android/net/connectivity/ConnectivityCompatChanges.java b/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
index 317854b..2261c69 100644
--- a/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
+++ b/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
@@ -100,9 +100,9 @@
     public static final long ENABLE_MATCH_LOCAL_NETWORK = 319212206L;
 
     /**
-     * On Android {@link android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM} or higher releases,
-     * network access from apps targeting Android 36 or higher that do not have the
-     * {@link android.Manifest.permission#INTERNET} permission is considered blocked.
+     * On Android versions starting from 37, network access from apps targeting
+     * Android 37 or higher, that do not have the {@link android.Manifest.permission#INTERNET}
+     * permission, is considered blocked.
      * This results in API behaviors change for apps without
      * {@link android.Manifest.permission#INTERNET} permission.
      * {@link android.net.NetworkInfo} returned from {@link android.net.ConnectivityManager} APIs
@@ -115,10 +115,12 @@
      * network access from apps without {@link android.Manifest.permission#INTERNET} permission is
      * considered not blocked even though apps cannot access any networks.
      *
+     * TODO: b/400903101 - Update the target SDK version once it's finalized.
+     *
      * @hide
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+    @EnabledAfter(targetSdkVersion = 36)
     public static final long NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION = 333340911L;
 
     /**
diff --git a/service-t/Android.bp b/service-t/Android.bp
index d2e2a80..ab38c7a 100644
--- a/service-t/Android.bp
+++ b/service-t/Android.bp
@@ -29,6 +29,7 @@
     name: "service-connectivity-tiramisu-sources",
     srcs: [
         "src/**/*.java",
+        ":vcn-location-sources",
     ],
     visibility: ["//visibility:private"],
 }
diff --git a/service-t/src/com/android/server/ConnectivityServiceInitializer.java b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
index 5d23fdc..5ef1aef 100644
--- a/service-t/src/com/android/server/ConnectivityServiceInitializer.java
+++ b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
@@ -30,6 +30,9 @@
 import com.android.server.nearby.NearbyService;
 import com.android.server.net.ct.CertificateTransparencyService;
 import com.android.server.thread.ThreadNetworkService;
+import com.android.server.vcn.VcnLocation;
+
+import java.lang.reflect.Constructor;
 
 /**
  * Connectivity service initializer for core networking. This is called by system server to create
@@ -37,6 +40,9 @@
  */
 public final class ConnectivityServiceInitializer extends SystemService {
     private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName();
+    private static final String CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS =
+            "com.android.server.ConnectivityServiceInitializerB";
+
     private final ConnectivityNativeService mConnectivityNative;
     private final ConnectivityService mConnectivity;
     private final IpSecService mIpSecService;
@@ -45,6 +51,7 @@
     private final EthernetServiceImpl mEthernetServiceImpl;
     private final ThreadNetworkService mThreadNetworkService;
     private final CertificateTransparencyService mCertificateTransparencyService;
+    private final SystemService mConnectivityServiceInitializerB;
 
     public ConnectivityServiceInitializer(Context context) {
         super(context);
@@ -58,6 +65,7 @@
         mNearbyService = createNearbyService(context);
         mThreadNetworkService = createThreadNetworkService(context);
         mCertificateTransparencyService = createCertificateTransparencyService(context);
+        mConnectivityServiceInitializerB = createConnectivityServiceInitializerB(context);
     }
 
     @Override
@@ -99,6 +107,11 @@
             publishBinderService(ThreadNetworkManager.SERVICE_NAME, mThreadNetworkService,
                     /* allowIsolated= */ false);
         }
+
+        if (mConnectivityServiceInitializerB != null) {
+            Log.i(TAG, "ConnectivityServiceInitializerB#onStart");
+            mConnectivityServiceInitializerB.onStart();
+        }
     }
 
     @Override
@@ -118,6 +131,10 @@
         if (SdkLevel.isAtLeastV() && mCertificateTransparencyService != null) {
             mCertificateTransparencyService.onBootPhase(phase);
         }
+
+        if (mConnectivityServiceInitializerB != null) {
+            mConnectivityServiceInitializerB.onBootPhase(phase);
+        }
     }
 
     /**
@@ -202,4 +219,28 @@
                 ? new CertificateTransparencyService(context)
                 : null;
     }
+
+    // TODO: b/374174952 After VCN code is moved to the Connectivity folder, merge
+    // ConnectivityServiceInitializerB into ConnectivityServiceInitializer and directly create and
+    // register VcnManagementService in ConnectivityServiceInitializer
+    /** Return ConnectivityServiceInitializerB instance if enable, otherwise null. */
+    @Nullable
+    private SystemService createConnectivityServiceInitializerB(Context context) {
+        if (!VcnLocation.IS_VCN_IN_MAINLINE || !SdkLevel.isAtLeastB()) {
+            return null;
+        }
+
+        try {
+            final Class<?> connectivityServiceInitializerBClass =
+                    Class.forName(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
+            final Constructor constructor =
+                    connectivityServiceInitializerBClass.getConstructor(Context.class);
+
+            return (SystemService) constructor.newInstance(context);
+        } catch (Exception e) {
+            Log.e(TAG, "Fail to load ConnectivityServiceInitializerB " + e);
+        }
+
+        return null;
+    }
 }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index 3430196..d55df6f 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -1843,11 +1843,11 @@
         final DetailedBlockedStatusCallback remoteUidCallback = new DetailedBlockedStatusCallback();
 
         // Create a TUN interface
-        final FileDescriptor tunFd = runWithShellPermissionIdentity(() -> {
+        final ParcelFileDescriptor tunFd = runWithShellPermissionIdentity(() -> {
             final TestNetworkManager tnm = mTestContext.getSystemService(TestNetworkManager.class);
             final TestNetworkInterface iface = tnm.createTunInterface(List.of(
                     TEST_IP4_DST_ADDR, TEST_IP6_DST_ADDR));
-            return iface.getFileDescriptor().getFileDescriptor();
+            return iface.getFileDescriptor();
         }, MANAGE_TEST_NETWORKS);
 
         // Create a remote UDP socket
@@ -1861,7 +1861,7 @@
             remoteUidCallback.expectAvailableCallbacksWithBlockedReasonNone(network);
 
             // The remote UDP socket can receive packets coming from the TUN interface
-            checkBlockIncomingPacket(tunFd, remoteUdpFd, EXPECT_PASS);
+            checkBlockIncomingPacket(tunFd.getFileDescriptor(), remoteUdpFd, EXPECT_PASS);
 
             // Lockdown uid that has the remote UDP socket
             runWithShellPermissionIdentity(() -> {
@@ -1877,7 +1877,7 @@
             if (SdkLevel.isAtLeastT()) {
                 // On T and above, lockdown rule drop packets not coming from lo regardless of the
                 // VPN connectivity.
-                checkBlockIncomingPacket(tunFd, remoteUdpFd, EXPECT_BLOCK);
+                checkBlockIncomingPacket(tunFd.getFileDescriptor(), remoteUdpFd, EXPECT_BLOCK);
             }
 
             // Start the VPN that has default routes. This VPN should have interface filtering rule
@@ -1889,9 +1889,9 @@
                     null /* proxyInfo */, null /* underlyingNetworks */,
                     false /* isAlwaysMetered */);
 
-            checkBlockIncomingPacket(tunFd, remoteUdpFd, EXPECT_BLOCK);
+            checkBlockIncomingPacket(tunFd.getFileDescriptor(), remoteUdpFd, EXPECT_BLOCK);
         }, /* cleanup */ () -> {
-                Os.close(tunFd);
+                tunFd.close();
             }, /* cleanup */ () -> {
                 Os.close(remoteUdpFd);
             }, /* cleanup */ () -> {
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt
index 0a8f108..976dfa9 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt
@@ -208,7 +208,10 @@
     @Test
     fun testServiceExpiredAndSendCallbacks() {
         val serviceCache = MdnsServiceCache(
-                thread.looper, makeFlags(isExpiredServicesRemovalEnabled = true), clock)
+                thread.looper,
+            makeFlags(isExpiredServicesRemovalEnabled = true),
+            clock
+        )
         // Register service expired callbacks
         val callback1 = ExpiredRecord()
         val callback2 = ExpiredRecord()
@@ -218,12 +221,21 @@
         doReturn(TEST_ELAPSED_REALTIME_MS).`when`(clock).elapsedRealtime()
 
         // Add multiple services with different ttl time.
-        addOrUpdateService(serviceCache, cacheKey1, createResponse(SERVICE_NAME_1, SERVICE_TYPE_1,
-                DEFAULT_TTL_TIME_MS))
-        addOrUpdateService(serviceCache, cacheKey1, createResponse(SERVICE_NAME_2, SERVICE_TYPE_1,
-                DEFAULT_TTL_TIME_MS + 20L))
-        addOrUpdateService(serviceCache, cacheKey2, createResponse(SERVICE_NAME_3, SERVICE_TYPE_2,
-                DEFAULT_TTL_TIME_MS + 10L))
+        addOrUpdateService(serviceCache, cacheKey1, createResponse(
+            SERVICE_NAME_1,
+            SERVICE_TYPE_1,
+                DEFAULT_TTL_TIME_MS
+        ))
+        addOrUpdateService(serviceCache, cacheKey1, createResponse(
+            SERVICE_NAME_2,
+            SERVICE_TYPE_1,
+                DEFAULT_TTL_TIME_MS + 20L
+        ))
+        addOrUpdateService(serviceCache, cacheKey2, createResponse(
+            SERVICE_NAME_3,
+            SERVICE_TYPE_2,
+                DEFAULT_TTL_TIME_MS + 10L
+        ))
 
         // Check the service expiration immediately. Should be no callback.
         assertEquals(2, getServices(serviceCache, cacheKey1).size)
@@ -252,16 +264,25 @@
     @Test
     fun testRemoveExpiredServiceWhenGetting() {
         val serviceCache = MdnsServiceCache(
-                thread.looper, makeFlags(isExpiredServicesRemovalEnabled = true), clock)
+                thread.looper,
+            makeFlags(isExpiredServicesRemovalEnabled = true),
+            clock
+        )
 
         doReturn(TEST_ELAPSED_REALTIME_MS).`when`(clock).elapsedRealtime()
-        addOrUpdateService(serviceCache, cacheKey1,
-                createResponse(SERVICE_NAME_1, SERVICE_TYPE_1, 1L /* ttlTime */))
+        addOrUpdateService(
+            serviceCache,
+            cacheKey1,
+                createResponse(SERVICE_NAME_1, SERVICE_TYPE_1, 1L /* ttlTime */)
+        )
         doReturn(TEST_ELAPSED_REALTIME_MS + 2L).`when`(clock).elapsedRealtime()
         assertNull(getService(serviceCache, SERVICE_NAME_1, cacheKey1))
 
-        addOrUpdateService(serviceCache, cacheKey2,
-                createResponse(SERVICE_NAME_2, SERVICE_TYPE_2, 3L /* ttlTime */))
+        addOrUpdateService(
+            serviceCache,
+            cacheKey2,
+                createResponse(SERVICE_NAME_2, SERVICE_TYPE_2, 3L /* ttlTime */)
+        )
         doReturn(TEST_ELAPSED_REALTIME_MS + 4L).`when`(clock).elapsedRealtime()
         assertEquals(0, getServices(serviceCache, cacheKey2).size)
     }
@@ -334,8 +355,11 @@
     ): MdnsResponse {
         val serviceName = "$serviceInstanceName.$serviceType".split(".").toTypedArray()
         val response = MdnsResponse(
-                0 /* now */, "$serviceInstanceName.$serviceType".split(".").toTypedArray(),
-                socketKey.interfaceIndex, socketKey.network)
+                0 /* now */,
+            "$serviceInstanceName.$serviceType".split(".").toTypedArray(),
+                socketKey.interfaceIndex,
+            socketKey.network
+        )
 
         // Set PTR record
         val pointerRecord = MdnsPointerRecord(
@@ -343,7 +367,8 @@
                 TEST_ELAPSED_REALTIME_MS /* receiptTimeMillis */,
                 false /* cacheFlush */,
                 ttlTime /* ttlMillis */,
-                serviceName)
+                serviceName
+        )
         response.addPointerRecord(pointerRecord)
 
         // Set SRV record.
@@ -355,7 +380,8 @@
                 0 /* servicePriority */,
                 0 /* serviceWeight */,
                 12345 /* port */,
-                arrayOf("hostname"))
+                arrayOf("hostname")
+        )
         response.serviceRecord = serviceRecord
         return response
     }