Merge "Update lnp app compat to be enabled after cur development version" into main
diff --git a/bpf/tests/mts/bpf_existence_test.cpp b/bpf/tests/mts/bpf_existence_test.cpp
index 2cfa546..0ecda3d 100644
--- a/bpf/tests/mts/bpf_existence_test.cpp
+++ b/bpf/tests/mts/bpf_existence_test.cpp
@@ -21,7 +21,6 @@
 #include <string>
 
 #include <android-base/properties.h>
-#include <android-modules-utils/sdk_level.h>
 #include <android/api-level.h>
 #include <bpf/BpfUtils.h>
 
@@ -32,11 +31,6 @@
 using std::string;
 
 using android::bpf::isAtLeastKernelVersion;
-using android::modules::sdklevel::IsAtLeastR;
-using android::modules::sdklevel::IsAtLeastS;
-using android::modules::sdklevel::IsAtLeastT;
-using android::modules::sdklevel::IsAtLeastU;
-using android::modules::sdklevel::IsAtLeastV;
 
 #define PLATFORM "/sys/fs/bpf/"
 #define TETHERING "/sys/fs/bpf/tethering/"
@@ -48,10 +42,15 @@
 class BpfExistenceTest : public ::testing::Test {
 };
 
-//ToDo: replace isAtLeast25Q2 with IsAtLeastB once sdk_level have been upgraded to 36 on aosp/main
 const bool unreleased = (android::base::GetProperty("ro.build.version.codename", "REL") != "REL");
-const int api_level = unreleased ? __ANDROID_API_FUTURE__ : android_get_device_api_level();
-const bool isAtLeast25Q2 = (api_level > __ANDROID_API_V__);
+const int api_level = unreleased ? 10000 : android_get_device_api_level();
+const bool isAtLeastR = (api_level >= 30);
+const bool isAtLeastS = (api_level >= 31);
+// Sv2 is 32
+const bool isAtLeastT = (api_level >= 33);
+const bool isAtLeastU = (api_level >= 34);
+const bool isAtLeastV = (api_level >= 35);
+const bool isAtLeast25Q2 = (api_level >= 36);
 
 // Part of Android R platform (for 4.9+), but mainlined in S
 static const set<string> PLATFORM_ONLY_IN_R = {
@@ -194,33 +193,33 @@
     // and for the presence of mainline stuff.
 
     // Note: Q is no longer supported by mainline
-    ASSERT_TRUE(IsAtLeastR());
+    ASSERT_TRUE(isAtLeastR);
 
     // R can potentially run on pre-4.9 kernel non-eBPF capable devices.
-    DO_EXPECT(IsAtLeastR() && !IsAtLeastS() && isAtLeastKernelVersion(4, 9, 0), PLATFORM_ONLY_IN_R);
+    DO_EXPECT(isAtLeastR && !isAtLeastS && isAtLeastKernelVersion(4, 9, 0), PLATFORM_ONLY_IN_R);
 
     // S requires Linux Kernel 4.9+ and thus requires eBPF support.
-    if (IsAtLeastS()) ASSERT_TRUE(isAtLeastKernelVersion(4, 9, 0));
-    DO_EXPECT(IsAtLeastS(), MAINLINE_FOR_S_PLUS);
+    if (isAtLeastS) ASSERT_TRUE(isAtLeastKernelVersion(4, 9, 0));
+    DO_EXPECT(isAtLeastS, MAINLINE_FOR_S_PLUS);
 
     // Nothing added or removed in SCv2.
 
     // T still only requires Linux Kernel 4.9+.
-    DO_EXPECT(IsAtLeastT(), MAINLINE_FOR_T_PLUS);
-    DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(4, 14, 0), MAINLINE_FOR_T_4_14_PLUS);
-    DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(4, 19, 0), MAINLINE_FOR_T_4_19_PLUS);
-    DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_T_5_10_PLUS);
-    DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(5, 15, 0), MAINLINE_FOR_T_5_15_PLUS);
+    DO_EXPECT(isAtLeastT, MAINLINE_FOR_T_PLUS);
+    DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(4, 14, 0), MAINLINE_FOR_T_4_14_PLUS);
+    DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(4, 19, 0), MAINLINE_FOR_T_4_19_PLUS);
+    DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_T_5_10_PLUS);
+    DO_EXPECT(isAtLeastT && isAtLeastKernelVersion(5, 15, 0), MAINLINE_FOR_T_5_15_PLUS);
 
     // U requires Linux Kernel 4.14+, but nothing (as yet) added or removed in U.
-    if (IsAtLeastU()) ASSERT_TRUE(isAtLeastKernelVersion(4, 14, 0));
-    DO_EXPECT(IsAtLeastU(), MAINLINE_FOR_U_PLUS);
-    DO_EXPECT(IsAtLeastU() && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_U_5_10_PLUS);
+    if (isAtLeastU) ASSERT_TRUE(isAtLeastKernelVersion(4, 14, 0));
+    DO_EXPECT(isAtLeastU, MAINLINE_FOR_U_PLUS);
+    DO_EXPECT(isAtLeastU && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_U_5_10_PLUS);
 
     // V requires Linux Kernel 4.19+, but nothing (as yet) added or removed in V.
-    if (IsAtLeastV()) ASSERT_TRUE(isAtLeastKernelVersion(4, 19, 0));
-    DO_EXPECT(IsAtLeastV(), MAINLINE_FOR_V_PLUS);
-    DO_EXPECT(IsAtLeastV() && isAtLeastKernelVersion(5, 4, 0), MAINLINE_FOR_V_5_4_PLUS);
+    if (isAtLeastV) ASSERT_TRUE(isAtLeastKernelVersion(4, 19, 0));
+    DO_EXPECT(isAtLeastV, MAINLINE_FOR_V_PLUS);
+    DO_EXPECT(isAtLeastV && isAtLeastKernelVersion(5, 4, 0), MAINLINE_FOR_V_5_4_PLUS);
 
     if (isAtLeast25Q2) ASSERT_TRUE(isAtLeastKernelVersion(5, 4, 0));
     DO_EXPECT(isAtLeast25Q2, MAINLINE_FOR_25Q2_PLUS);
diff --git a/networksecurity/TEST_MAPPING b/networksecurity/TEST_MAPPING
index 4fd5a45..448ee84 100644
--- a/networksecurity/TEST_MAPPING
+++ b/networksecurity/TEST_MAPPING
@@ -1,21 +1,4 @@
 {
-  "tethering-mainline-presubmit": [
-    {
-      "name": "CtsNetSecConfigCertificateTransparencyTestCases"
-    },
-    {
-      "name": "CtsNetSecConfigCertificateTransparencyDefaultTestCases"
-    },
-    {
-      "name": "NetSecConfigCertificateTransparencySctLogListTestCases"
-    },
-    {
-      "name": "NetSecConfigCertificateTransparencySctNoLogListTestCases"
-    },
-    {
-      "name": "NetworkSecurityUnitTests"
-    }
-  ],
   "presubmit": [
     {
       "name": "CtsNetSecConfigCertificateTransparencyTestCases"
diff --git a/service/src/com/android/server/L2capNetworkProvider.java b/service/src/com/android/server/L2capNetworkProvider.java
index 441f084..72bd858 100644
--- a/service/src/com/android/server/L2capNetworkProvider.java
+++ b/service/src/com/android/server/L2capNetworkProvider.java
@@ -16,7 +16,7 @@
 
 package com.android.server;
 
-import static android.net.L2capNetworkSpecifier.HEADER_COMPRESSION_6LOWPAN;
+import static android.content.pm.PackageManager.FEATURE_BLUETOOTH_LE;
 import static android.net.L2capNetworkSpecifier.HEADER_COMPRESSION_ANY;
 import static android.net.L2capNetworkSpecifier.PSM_ANY;
 import static android.net.L2capNetworkSpecifier.ROLE_CLIENT;
@@ -30,7 +30,6 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS;
 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
-import static android.content.pm.PackageManager.FEATURE_BLUETOOTH_LE;
 import static android.system.OsConstants.F_GETFL;
 import static android.system.OsConstants.F_SETFL;
 import static android.system.OsConstants.O_NONBLOCK;
@@ -50,10 +49,8 @@
 import android.net.NetworkProvider.NetworkOfferCallback;
 import android.net.NetworkRequest;
 import android.net.NetworkScore;
-import android.net.NetworkSpecifier;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.system.Os;
 import android.util.ArrayMap;
@@ -129,12 +126,7 @@
         }
 
         // TODO: consider moving this into L2capNetworkSpecifier as #isValidServerReservation().
-        private boolean isValidL2capSpecifier(@Nullable NetworkSpecifier spec) {
-            if (spec == null) return false;
-            // If spec is not null, L2capNetworkSpecifier#canBeSatisfiedBy() guarantees the
-            // specifier is of type L2capNetworkSpecifier.
-            final L2capNetworkSpecifier l2capSpec = (L2capNetworkSpecifier) spec;
-
+        private boolean isValidL2capServerSpecifier(L2capNetworkSpecifier l2capSpec) {
             // The ROLE_SERVER offer can be satisfied by a ROLE_ANY request.
             if (l2capSpec.getRole() != ROLE_SERVER) return false;
 
@@ -152,9 +144,13 @@
 
         @Override
         public void onNetworkNeeded(NetworkRequest request) {
-            Log.d(TAG, "New reservation request: " + request);
-            if (!isValidL2capSpecifier(request.getNetworkSpecifier())) {
-                Log.w(TAG, "Ignoring invalid reservation request: " + request);
+            // The NetworkSpecifier is guaranteed to be either null or an L2capNetworkSpecifier, so
+            // this cast is safe.
+            final L2capNetworkSpecifier specifier =
+                    (L2capNetworkSpecifier) request.getNetworkSpecifier();
+            if (specifier == null) return;
+            if (!isValidL2capServerSpecifier(specifier)) {
+                Log.i(TAG, "Ignoring invalid reservation request: " + request);
                 return;
             }
 
@@ -239,36 +235,15 @@
     }
 
     @Nullable
-    private static ParcelFileDescriptor createTunInterface(String ifname) {
-        final ParcelFileDescriptor fd;
-        try {
-            fd = ParcelFileDescriptor.adoptFd(
-                    ServiceConnectivityJni.createTunTap(
-                            true /*isTun*/, true /*hasCarrier*/, true /*setIffMulticast*/, ifname));
-            ServiceConnectivityJni.bringUpInterface(ifname);
-            // TODO: consider adding a parameter to createTunTap() (or the Builder that should
-            // be added) to configure i/o blocking.
-            final int flags = Os.fcntlInt(fd.getFileDescriptor(), F_GETFL, 0);
-            Os.fcntlInt(fd.getFileDescriptor(), F_SETFL, flags & ~O_NONBLOCK);
-        } catch (Exception e) {
-            // Note: createTunTap currently throws an IllegalStateException on failure.
-            // TODO: native functions should throw ErrnoException.
-            Log.e(TAG, "Failed to create tun interface", e);
-            return null;
-        }
-        return fd;
-    }
-
-    @Nullable
     private L2capNetwork createL2capNetwork(BluetoothSocket socket, NetworkCapabilities caps,
             L2capNetwork.ICallback cb) {
         final String ifname = TUN_IFNAME + String.valueOf(sTunIndex++);
-        final ParcelFileDescriptor tunFd = createTunInterface(ifname);
+        final ParcelFileDescriptor tunFd = mDeps.createTunInterface(ifname);
         if (tunFd == null) {
             return null;
         }
 
-        return new L2capNetwork(mHandler, mContext, mProvider, ifname, socket, tunFd, caps, cb);
+        return L2capNetwork.create(mHandler, mContext, mProvider, ifname, socket, tunFd, caps, cb);
     }
 
     private static void closeBluetoothSocket(BluetoothSocket socket) {
@@ -516,12 +491,7 @@
             return true;
         }
 
-        private boolean isValidL2capSpecifier(@Nullable NetworkSpecifier spec) {
-            if (spec == null) return false;
-
-            // If not null, guaranteed to be L2capNetworkSepcifier.
-            final L2capNetworkSpecifier l2capSpec = (L2capNetworkSpecifier) spec;
-
+        private boolean isValidL2capClientSpecifier(L2capNetworkSpecifier l2capSpec) {
             // The ROLE_CLIENT offer can be satisfied by a ROLE_ANY request.
             if (l2capSpec.getRole() != ROLE_CLIENT) return false;
 
@@ -541,14 +511,16 @@
 
         @Override
         public void onNetworkNeeded(NetworkRequest request) {
-            Log.d(TAG, "New client network request: " + request);
-            if (!isValidL2capSpecifier(request.getNetworkSpecifier())) {
-                Log.w(TAG, "Ignoring invalid client request: " + request);
+            // The NetworkSpecifier is guaranteed to be either null or an L2capNetworkSpecifier, so
+            // this cast is safe.
+            final L2capNetworkSpecifier requestSpecifier =
+                    (L2capNetworkSpecifier) request.getNetworkSpecifier();
+            if (requestSpecifier == null) return;
+            if (!isValidL2capClientSpecifier(requestSpecifier)) {
+                Log.i(TAG, "Ignoring invalid client request: " + request);
                 return;
             }
 
-            final L2capNetworkSpecifier requestSpecifier =
-                    (L2capNetworkSpecifier) request.getNetworkSpecifier();
              // Check whether this exact request is already being tracked.
             final ClientRequestInfo cri = mClientNetworkRequests.get(requestSpecifier);
             if (cri != null) {
@@ -656,6 +628,29 @@
             thread.start();
             return thread;
         }
+
+        @Nullable
+        public ParcelFileDescriptor createTunInterface(String ifname) {
+            final ParcelFileDescriptor fd;
+            try {
+                fd = ParcelFileDescriptor.adoptFd(ServiceConnectivityJni.createTunTap(
+                        true /*isTun*/,
+                        true /*hasCarrier*/,
+                        true /*setIffMulticast*/,
+                        ifname));
+                ServiceConnectivityJni.bringUpInterface(ifname);
+                // TODO: consider adding a parameter to createTunTap() (or the Builder that should
+                // be added) to configure i/o blocking.
+                final int flags = Os.fcntlInt(fd.getFileDescriptor(), F_GETFL, 0);
+                Os.fcntlInt(fd.getFileDescriptor(), F_SETFL, flags & ~O_NONBLOCK);
+            } catch (Exception e) {
+                // Note: createTunTap currently throws an IllegalStateException on failure.
+                // TODO: native functions should throw ErrnoException.
+                Log.e(TAG, "Failed to create tun interface", e);
+                return null;
+            }
+            return fd;
+        }
     }
 
     public L2capNetworkProvider(Context context) {
diff --git a/service/src/com/android/server/net/L2capNetwork.java b/service/src/com/android/server/net/L2capNetwork.java
index 594d273..b624bca 100644
--- a/service/src/com/android/server/net/L2capNetwork.java
+++ b/service/src/com/android/server/net/L2capNetwork.java
@@ -42,10 +42,8 @@
     private static final NetworkScore NETWORK_SCORE = new NetworkScore.Builder().build();
     private final String mLogTag;
     private final Handler mHandler;
-    private final String mIfname;
     private final L2capPacketForwarder mForwarder;
     private final NetworkCapabilities mNetworkCapabilities;
-    private final L2capIpClient mIpClient;
     private final NetworkAgent mNetworkAgent;
 
     /** IpClient wrapper to handle IPv6 link-local provisioning for L2CAP tun.
@@ -59,7 +57,7 @@
         @Nullable
         private IpClientManager mIpClient;
         @Nullable
-        private LinkProperties mLinkProperties;
+        private volatile LinkProperties mLinkProperties;
 
         L2capIpClient(String logTag, Context context, String ifname) {
             mLogTag = logTag;
@@ -74,11 +72,24 @@
 
         @Override
         public void onProvisioningSuccess(LinkProperties lp) {
-            Log.d(mLogTag, "Successfully provisionined l2cap tun: " + lp);
+            Log.d(mLogTag, "Successfully provisioned l2cap tun: " + lp);
             mLinkProperties = lp;
             mOnProvisioningSuccessCv.open();
         }
 
+        @Override
+        public void onProvisioningFailure(LinkProperties lp) {
+            Log.i(mLogTag, "Failed to provision l2cap tun: " + lp);
+            mLinkProperties = null;
+            mOnProvisioningSuccessCv.open();
+        }
+
+        /**
+         * Starts IPv6 link-local provisioning.
+         *
+         * @return LinkProperties on success, null on failure.
+         */
+        @Nullable
         public LinkProperties start() {
             mOnIpClientCreatedCv.block();
             // mIpClient guaranteed non-null.
@@ -102,32 +113,27 @@
         void onNetworkUnwanted(L2capNetwork network);
     }
 
-    public L2capNetwork(Handler handler, Context context, NetworkProvider provider, String ifname,
-            BluetoothSocket socket, ParcelFileDescriptor tunFd,
-            NetworkCapabilities networkCapabilities, ICallback cb) {
-        // TODO: add a check that this constructor is invoked on the handler thread.
-        mLogTag = String.format("L2capNetwork[%s]", ifname);
+    public L2capNetwork(String logTag, Handler handler, Context context, NetworkProvider provider,
+            BluetoothSocket socket, ParcelFileDescriptor tunFd, NetworkCapabilities nc,
+            LinkProperties lp, ICallback cb) {
+        mLogTag = logTag;
         mHandler = handler;
-        mIfname = ifname;
+        mNetworkCapabilities = nc;
 
-        // Guaranteed non-null.
-        final L2capNetworkSpecifier spec =
-                (L2capNetworkSpecifier) networkCapabilities.getNetworkSpecifier();
+        final L2capNetworkSpecifier spec = (L2capNetworkSpecifier) nc.getNetworkSpecifier();
         final boolean compressHeaders = spec.getHeaderCompression() == HEADER_COMPRESSION_6LOWPAN;
+
         mForwarder = new L2capPacketForwarder(handler, tunFd, socket, compressHeaders, () -> {
             // TODO: add a check that this callback is invoked on the handler thread.
             cb.onError(L2capNetwork.this);
         });
-        mNetworkCapabilities = networkCapabilities;
-        mIpClient = new L2capIpClient(mLogTag, context, ifname);
-        final LinkProperties linkProperties = mIpClient.start();
 
         final NetworkAgentConfig config = new NetworkAgentConfig.Builder().build();
         mNetworkAgent = new NetworkAgent(context, mHandler.getLooper(), mLogTag,
-                networkCapabilities, linkProperties, NETWORK_SCORE, config, provider) {
+                nc, lp, NETWORK_SCORE, config, provider) {
             @Override
             public void onNetworkUnwanted() {
-                Log.i(mLogTag, mIfname + ": Network is unwanted");
+                Log.i(mLogTag, "Network is unwanted");
                 // TODO: add a check that this callback is invoked on the handler thread.
                 cb.onNetworkUnwanted(L2capNetwork.this);
             }
@@ -136,6 +142,24 @@
         mNetworkAgent.markConnected();
     }
 
+    /** Create an L2capNetwork or return null on failure. */
+    @Nullable
+    public static L2capNetwork create(Handler handler, Context context, NetworkProvider provider,
+            String ifname, BluetoothSocket socket, ParcelFileDescriptor tunFd,
+            NetworkCapabilities nc, ICallback cb) {
+        // TODO: add a check that this function is invoked on the handler thread.
+        final String logTag = String.format("L2capNetwork[%s]", ifname);
+
+        // L2capIpClient#start() blocks until provisioning either succeeds (and returns
+        // LinkProperties) or fails (and returns null).
+        // Note that since L2capNetwork is using IPv6 link-local provisioning the most likely
+        // (only?) failure mode is due to the interface disappearing.
+        final LinkProperties lp = new L2capIpClient(logTag, context, ifname).start();
+        if (lp == null) return null;
+
+        return new L2capNetwork(logTag, handler, context, provider, socket, tunFd, nc, lp, cb);
+    }
+
     /** Get the NetworkCapabilities used for this Network */
     public NetworkCapabilities getNetworkCapabilities() {
         return mNetworkCapabilities;