Add jarjar rule for com.android.testutils.TestBpfMap am: 3157918fc9

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1971020

Change-Id: I31fd26dce1a06510e11e7d1da5c08fb6ea6805de
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index ecbaf61..6d04326 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -99,7 +99,6 @@
     ],
     min_sdk_version: "30",
     header_libs: [
-        "bpf_syscall_wrappers",
         "bpf_connectivity_headers",
     ],
     srcs: [
@@ -112,7 +111,6 @@
     static_libs: [
         "libnet_utils_device_common_bpfjni",
         "libnetjniutils",
-        "libtcutils",
     ],
 
     // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
@@ -210,5 +208,4 @@
 sdk {
     name: "tethering-module-sdk",
     bootclasspath_fragments: ["com.android.tethering-bootclasspath-fragment"],
-    systemserverclasspath_fragments: ["com.android.tethering-systemserverclasspath-fragment"],
 }
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index ea3f8d6..e16e56f 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -22,16 +22,16 @@
 // different value depending on the branch.
 java_defaults {
     name: "ConnectivityNextEnableDefaults",
-    enabled: true,
+    enabled: false,
 }
 apex_defaults {
     name: "ConnectivityApexDefaults",
     // Tethering app to include in the AOSP apex. Branches that disable the "next" targets may use
     // a stable tethering app instead, but will generally override the AOSP apex to use updatable
     // package names and keys, so that apex will be unused anyway.
-    apps: ["TetheringNext"], // Replace to "Tethering" if ConnectivityNextEnableDefaults is false.
+    apps: ["Tethering"], // Replace to "Tethering" if ConnectivityNextEnableDefaults is false.
 }
-enable_tethering_next_apex = true
+enable_tethering_next_apex = false
 // This is a placeholder comment to avoid merge conflicts
 // as the above target may have different "enabled" values
 // depending on the branch
@@ -45,8 +45,8 @@
     bootclasspath_fragments: [
         "com.android.tethering-bootclasspath-fragment",
     ],
-    systemserverclasspath_fragments: [
-        "com.android.tethering-systemserverclasspath-fragment",
+    java_libs: [
+        "service-connectivity",
     ],
     multilib: {
         first: {
@@ -100,7 +100,7 @@
     name: "com.android.tethering-bootclasspath-fragment",
     contents: [
         "framework-connectivity",
-        "framework-connectivity-tiramisu",
+        // Changed in sc-mainline-prod only: no framework-connectivity-tiramisu
         "framework-tethering",
     ],
     apex_available: ["com.android.tethering"],
@@ -123,22 +123,18 @@
     // modified by the Soong or platform compat team.
     hidden_api: {
         max_target_r_low_priority: [
-            "hiddenapi/hiddenapi-max-target-r-loprio.txt",
+            // Changed in sc-mainline-prod only: no list for
+            // framework-connectivity-tiramisu APIs as it is not in the APEX
 	],
         max_target_o_low_priority: [
             "hiddenapi/hiddenapi-max-target-o-low-priority.txt",
-            "hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt",
+            // Changed in sc-mainline-prod only: no list for
+            // framework-connectivity-tiramisu APIs as it is not in the APEX
 	],
         unsupported: ["hiddenapi/hiddenapi-unsupported.txt"],
     },
 }
 
-systemserverclasspath_fragment {
-    name: "com.android.tethering-systemserverclasspath-fragment",
-    standalone_contents: ["service-connectivity"],
-    apex_available: ["com.android.tethering"],
-}
-
 override_apex {
     name: "com.android.tethering.inprocess",
     base: "com.android.tethering",
diff --git a/Tethering/apex/canned_fs_config b/Tethering/apex/canned_fs_config
index 06e9617..5a03347 100644
--- a/Tethering/apex/canned_fs_config
+++ b/Tethering/apex/canned_fs_config
@@ -1,2 +1,2 @@
-/bin/for-system 0 1000 0550
+/bin/for-system 0 1000 0750
 /bin/for-system/clatd 1029 1029 06755
diff --git a/bpf_progs/bpf_shared.h b/bpf_progs/bpf_shared.h
index f0df97b..2ddc7b8 100644
--- a/bpf_progs/bpf_shared.h
+++ b/bpf_progs/bpf_shared.h
@@ -130,7 +130,8 @@
     STANDBY_MATCH = (1 << 3),
     POWERSAVE_MATCH = (1 << 4),
     RESTRICTED_MATCH = (1 << 5),
-    IIF_MATCH = (1 << 6),
+    LOW_POWER_STANDBY_MATCH = (1 << 6),
+    IIF_MATCH = (1 << 7),
 };
 
 enum BpfPermissionMatch {
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index f0af8b4..c1a74e7 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -210,6 +210,9 @@
         if ((enabledRules & RESTRICTED_MATCH) && !(uidRules & RESTRICTED_MATCH)) {
             return BPF_DROP;
         }
+        if ((enabledRules & LOW_POWER_STANDBY_MATCH) && !(uidRules & LOW_POWER_STANDBY_MATCH)) {
+            return BPF_DROP;
+        }
     }
     if (direction == BPF_INGRESS && (uidRules & IIF_MATCH)) {
         // Drops packets not coming from lo nor the allowlisted interface
diff --git a/buildstubs-t/Android.bp b/buildstubs-t/Android.bp
new file mode 100644
index 0000000..dfca6b3
--- /dev/null
+++ b/buildstubs-t/Android.bp
@@ -0,0 +1,49 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Placeholder empty filegroups to avoid merge conflicts on build rules
+// on a branch that does not have the filegroups
+
+filegroup {
+    name: "framework-connectivity-tiramisu-updatable-sources",
+    srcs: [],
+}
+
+filegroup {
+    name: "services.connectivity-tiramisu-updatable-sources",
+    srcs: ["stubs-src/**/*.java"],
+}
+
+// Empty replacement for framework-connectivity-tiramisu.impl and stubs,
+// as framework-connectivity is disabled in the branch
+java_library {
+    name: "framework-connectivity-tiramisu.impl",
+    min_sdk_version: "Tiramisu",
+    sdk_version: "module_current",
+    srcs: [],
+}
+
+java_library {
+    name: "framework-connectivity-tiramisu.stubs.module_lib",
+    min_sdk_version: "Tiramisu",
+    sdk_version: "module_current",
+    srcs: [],
+}
diff --git a/buildstubs-t/stubs-src/com/android/server/NsdService.java b/buildstubs-t/stubs-src/com/android/server/NsdService.java
new file mode 100644
index 0000000..8e32ffd
--- /dev/null
+++ b/buildstubs-t/stubs-src/com/android/server/NsdService.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+import java.io.FileDescriptor;
+
+/**
+ * Fake NsdService class for sc-mainline-prod,
+ * to allow building the T service-connectivity before sources
+ * are moved to the branch
+ */
+public final class NsdService implements IBinder {
+    /** Create instance */
+    public static NsdService create(Context ctx) throws InterruptedException {
+        throw new RuntimeException("This is a stub class");
+    }
+
+    @Override
+    public String getInterfaceDescriptor() throws RemoteException {
+        return null;
+    }
+
+    @Override
+    public boolean pingBinder() {
+        return false;
+    }
+
+    @Override
+    public boolean isBinderAlive() {
+        return false;
+    }
+
+    @Override
+    public IInterface queryLocalInterface(String descriptor) {
+        return null;
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, String[] args) throws RemoteException {}
+
+    @Override
+    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {}
+
+    @Override
+    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
+        return false;
+    }
+
+    @Override
+    public void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException {}
+
+    @Override
+    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
+        return false;
+    }
+}
diff --git a/framework-t/Android.bp b/framework-t/Android.bp
index b5aedeb..a08c06a 100644
--- a/framework-t/Android.bp
+++ b/framework-t/Android.bp
@@ -21,7 +21,7 @@
 
 java_defaults {
     name: "enable-framework-connectivity-t-targets",
-    enabled: true,
+    enabled: false,
 }
 // The above defaults can be used to disable framework-connectivity t
 // targets while minimizing merge conflicts in the build rules.
diff --git a/framework-t/api/current.txt b/framework-t/api/current.txt
index 0443456..7977cc5 100644
--- a/framework-t/api/current.txt
+++ b/framework-t/api/current.txt
@@ -3,6 +3,8 @@
 
   public final class NsdManager {
     method public void discoverServices(String, int, android.net.nsd.NsdManager.DiscoveryListener);
+    method public void discoverServices(@NonNull String, int, @Nullable android.net.Network, @NonNull android.net.nsd.NsdManager.DiscoveryListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void discoverServices(@NonNull String, int, @NonNull android.net.NetworkRequest, @NonNull android.net.nsd.NsdManager.DiscoveryListener);
     method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
     method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
     method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
@@ -43,12 +45,14 @@
     method public int describeContents();
     method public java.util.Map<java.lang.String,byte[]> getAttributes();
     method public java.net.InetAddress getHost();
+    method @Nullable public android.net.Network getNetwork();
     method public int getPort();
     method public String getServiceName();
     method public String getServiceType();
     method public void removeAttribute(String);
     method public void setAttribute(String, String);
     method public void setHost(java.net.InetAddress);
+    method public void setNetwork(@Nullable android.net.Network);
     method public void setPort(int);
     method public void setServiceName(String);
     method public void setServiceType(String);
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 92ede91..5246623 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -941,6 +941,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
     private final IConnectivityManager mService;
 
+    // LINT.IfChange(firewall_chain)
     /**
      * Firewall chain for device idle (doze mode).
      * Allowlist of apps that have network access in device idle.
@@ -991,6 +992,7 @@
         FIREWALL_CHAIN_LOW_POWER_STANDBY
     })
     public @interface FirewallChain {}
+    // LINT.ThenChange(packages/modules/Connectivity/service/native/include/Common.h)
 
     /**
      * A kludge to facilitate static access where a Context pointer isn't available, like in the
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index feb9fc1..b6cd760 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -1615,8 +1615,8 @@
      * <p>
      * Note that when used to register a network callback, this specifies the minimum acceptable
      * signal strength. When received as the state of an existing network it specifies the current
-     * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
-     * effect when requesting a callback.
+     * value. A value of {@link #SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has
+     * no effect when requesting a callback.
      *
      * @param signalStrength the bearer-specific signal strength.
      * @hide
diff --git a/netd/Android.bp b/netd/Android.bp
index 53c1bd4..b98a859 100644
--- a/netd/Android.bp
+++ b/netd/Android.bp
@@ -31,12 +31,10 @@
         "BpfHandler.cpp",
         "NetdUpdatable.cpp",
     ],
-    static_libs: [
-        "libnetdutils",
-    ],
     shared_libs: [
         "libbase",
         "liblog",
+        "libnetdutils",
     ],
     export_include_dirs: ["include"],
     header_abi_checker: {
diff --git a/service/Android.bp b/service/Android.bp
index 6d187ba..b307c5a 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -33,10 +33,8 @@
     srcs: [
         "jni/com_android_net_module_util/onload.cpp",
     ],
-    stl: "libc++_static",
     static_libs: [
         "libnet_utils_device_common_bpfjni",
-        "libtcutils",
     ],
     shared_libs: [
         "liblog",
@@ -62,21 +60,20 @@
         "jni/com_android_server_TestNetworkService.cpp",
         "jni/onload.cpp",
     ],
-    stl: "libc++_static",
     header_libs: [
         "bpf_connectivity_headers",
         "libbase_headers",
     ],
     static_libs: [
-        "libbase",
         "libclat",
         "libip_checksum",
-        "libnetdutils",
         "libnetjniutils",
         "libtraffic_controller",
         "netd_aidl_interface-lateststable-ndk",
     ],
     shared_libs: [
+        "libbase",
+        "libnetdutils",
         "liblog",
         "libnativehelper",
     ],
@@ -116,7 +113,7 @@
         "networkstack-client",
         "PlatformProperties",
         "service-connectivity-protos",
-        "NetworkStackApiCurrentShims",
+        "NetworkStackApiStableShims",
     ],
     apex_available: [
         "com.android.tethering",
diff --git a/service/native/Android.bp b/service/native/Android.bp
index a20c54f..cb26bc3 100644
--- a/service/native/Android.bp
+++ b/service/native/Android.bp
@@ -26,11 +26,8 @@
     ],
     header_libs: [
         "bpf_connectivity_headers",
-        "bpf_headers",
-        "bpf_syscall_wrappers",
     ],
     static_libs: [
-        "libnetdutils",
         // TrafficController would use the constants of INetd so that add
         // netd_aidl_interface-lateststable-ndk.
         "netd_aidl_interface-lateststable-ndk",
@@ -39,6 +36,7 @@
         // TODO: Find a good way to remove libbase.
         "libbase",
         "libcutils",
+        "libnetdutils",
         "libutils",
         "liblog",
     ],
diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp
index 51dd502..5981906 100644
--- a/service/native/TrafficController.cpp
+++ b/service/native/TrafficController.cpp
@@ -75,6 +75,7 @@
 const char* TrafficController::LOCAL_STANDBY = "fw_standby";
 const char* TrafficController::LOCAL_POWERSAVE = "fw_powersave";
 const char* TrafficController::LOCAL_RESTRICTED = "fw_restricted";
+const char* TrafficController::LOCAL_LOW_POWER_STANDBY = "fw_low_power_standby";
 
 static_assert(BPF_PERMISSION_INTERNET == INetd::PERMISSION_INTERNET,
               "Mismatch between BPF and AIDL permissions: PERMISSION_INTERNET");
@@ -97,6 +98,7 @@
     FLAG_MSG_TRANS(matchType, STANDBY_MATCH, match);
     FLAG_MSG_TRANS(matchType, POWERSAVE_MATCH, match);
     FLAG_MSG_TRANS(matchType, RESTRICTED_MATCH, match);
+    FLAG_MSG_TRANS(matchType, LOW_POWER_STANDBY_MATCH, match);
     FLAG_MSG_TRANS(matchType, IIF_MATCH, match);
     if (match) {
         return StringPrintf("Unknown match: %u", match);
@@ -426,6 +428,8 @@
             return ALLOWLIST;
         case RESTRICTED:
             return ALLOWLIST;
+        case LOW_POWER_STANDBY:
+            return ALLOWLIST;
         case NONE:
         default:
             return DENYLIST;
@@ -448,6 +452,9 @@
         case RESTRICTED:
             res = updateOwnerMapEntry(RESTRICTED_MATCH, uid, rule, type);
             break;
+        case LOW_POWER_STANDBY:
+            res = updateOwnerMapEntry(LOW_POWER_STANDBY_MATCH, uid, rule, type);
+            break;
         case NONE:
         default:
             ALOGW("Unknown child chain: %d", chain);
@@ -526,6 +533,8 @@
         res = replaceRulesInMap(POWERSAVE_MATCH, uids);
     } else if (!name.compare(LOCAL_RESTRICTED)) {
         res = replaceRulesInMap(RESTRICTED_MATCH, uids);
+    } else if (!name.compare(LOCAL_LOW_POWER_STANDBY)) {
+        res = replaceRulesInMap(LOW_POWER_STANDBY_MATCH, uids);
     } else {
         ALOGE("unknown chain name: %s", name.c_str());
         return -EINVAL;
@@ -562,6 +571,9 @@
         case RESTRICTED:
             match = RESTRICTED_MATCH;
             break;
+        case LOW_POWER_STANDBY:
+            match = LOW_POWER_STANDBY_MATCH;
+            break;
         default:
             return -EINVAL;
     }
diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp
index 39f3365..d0eca34 100644
--- a/service/native/TrafficControllerTest.cpp
+++ b/service/native/TrafficControllerTest.cpp
@@ -470,6 +470,7 @@
     checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH);
     checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH);
     checkUidOwnerRuleForChain(RESTRICTED, RESTRICTED_MATCH);
+    checkUidOwnerRuleForChain(LOW_POWER_STANDBY, LOW_POWER_STANDBY_MATCH);
     ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, ALLOWLIST));
     ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, ALLOWLIST));
 }
@@ -480,6 +481,7 @@
     checkUidMapReplace("fw_standby", uids, STANDBY_MATCH);
     checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH);
     checkUidMapReplace("fw_restricted", uids, RESTRICTED_MATCH);
+    checkUidMapReplace("fw_low_power_standby", uids, LOW_POWER_STANDBY_MATCH);
     ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
 }
 
diff --git a/service/native/include/Common.h b/service/native/include/Common.h
index 7c0b797..dc44845 100644
--- a/service/native/include/Common.h
+++ b/service/native/include/Common.h
@@ -27,11 +27,14 @@
 
 enum FirewallType { ALLOWLIST = INetd::FIREWALL_ALLOWLIST, DENYLIST = INetd::FIREWALL_DENYLIST };
 
+// LINT.IfChange(firewall_chain)
 enum ChildChain {
-    NONE = INetd::FIREWALL_CHAIN_NONE,
-    DOZABLE = INetd::FIREWALL_CHAIN_DOZABLE,
-    STANDBY = INetd::FIREWALL_CHAIN_STANDBY,
-    POWERSAVE = INetd::FIREWALL_CHAIN_POWERSAVE,
-    RESTRICTED = INetd::FIREWALL_CHAIN_RESTRICTED,
+    NONE = 0,
+    DOZABLE = 1,
+    STANDBY = 2,
+    POWERSAVE = 3,
+    RESTRICTED = 4,
+    LOW_POWER_STANDBY = 5,
     INVALID_CHAIN
 };
+// LINT.ThenChange(packages/modules/Connectivity/framework/src/android/net/ConnectivityManager.java)
diff --git a/service/native/include/TrafficController.h b/service/native/include/TrafficController.h
index ddcf445..e741dd6 100644
--- a/service/native/include/TrafficController.h
+++ b/service/native/include/TrafficController.h
@@ -99,6 +99,7 @@
     static const char* LOCAL_STANDBY;
     static const char* LOCAL_POWERSAVE;
     static const char* LOCAL_RESTRICTED;
+    static const char* LOCAL_LOW_POWER_STANDBY;
 
   private:
     /*
@@ -160,7 +161,7 @@
      * the map right now:
      * - Entry with UID_RULES_CONFIGURATION_KEY:
      *    Store the configuration for the current uid rules. It indicates the device
-     *    is in doze/powersave/standby/restricted mode.
+     *    is in doze/powersave/standby/restricted/low power standby mode.
      * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
      *    Stores the current live stats map that kernel program is writing to.
      *    Userspace can do scraping and cleaning job on the other one depending on the
diff --git a/service/native/libs/libclat/Android.bp b/service/native/libs/libclat/Android.bp
index 5e208d8..17ee996 100644
--- a/service/native/libs/libclat/Android.bp
+++ b/service/native/libs/libclat/Android.bp
@@ -21,8 +21,7 @@
     defaults: ["netd_defaults"],
     header_libs: [
         "bpf_connectivity_headers",
-        "bpf_headers",
-        "bpf_syscall_wrappers",
+        "libbase_headers",
     ],
     srcs: [
         "TcUtils.cpp",  // TODO: move to frameworks/libs/net
@@ -31,7 +30,6 @@
     ],
     stl: "libc++_static",
     static_libs: [
-        "libbase",
         "libip_checksum",
         "libnetdutils",  // for netdutils/UidConstants.h in bpf_shared.h
     ],
@@ -47,8 +45,6 @@
     test_suites: ["device-tests"],
     header_libs: [
         "bpf_connectivity_headers",
-        "bpf_headers",
-        "bpf_syscall_wrappers",
     ],
     srcs: [
         "TcUtilsTest.cpp",
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index a9a06e4..198190a 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -10912,6 +10912,10 @@
                 case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED:
                     mBpfNetMaps.replaceUidChain("fw_restricted", true /* isAllowList */, uids);
                     break;
+                case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY:
+                    mBpfNetMaps.replaceUidChain("fw_low_power_standby", true /* isAllowList */,
+                            uids);
+                    break;
                 default:
                     throw new IllegalArgumentException("replaceFirewallChain with invalid chain: "
                             + chain);
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 23814c9..9506081 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -15,6 +15,19 @@
  */
 package android.net.cts
 
+import android.Manifest.permission.MANAGE_TEST_NETWORKS
+import android.net.ConnectivityManager
+import android.net.ConnectivityManager.NetworkCallback
+import android.net.LinkProperties
+import android.net.Network
+import android.net.NetworkAgentConfig
+import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
+import android.net.NetworkCapabilities.TRANSPORT_TEST
+import android.net.NetworkRequest
+import android.net.TestNetworkInterface
+import android.net.TestNetworkManager
+import android.net.TestNetworkSpecifier
 import android.net.cts.NsdManagerTest.NsdDiscoveryRecord.DiscoveryEvent.DiscoveryStarted
 import android.net.cts.NsdManagerTest.NsdDiscoveryRecord.DiscoveryEvent.DiscoveryStopped
 import android.net.cts.NsdManagerTest.NsdDiscoveryRecord.DiscoveryEvent.ServiceFound
@@ -32,14 +45,27 @@
 import android.net.nsd.NsdManager.RegistrationListener
 import android.net.nsd.NsdManager.ResolveListener
 import android.net.nsd.NsdServiceInfo
+import android.os.HandlerThread
 import android.platform.test.annotations.AppModeFull
 import android.util.Log
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.runner.AndroidJUnit4
 import com.android.net.module.util.ArrayTrackRecord
 import com.android.net.module.util.TrackRecord
+import com.android.networkstack.apishim.ConstantsShim
+import com.android.networkstack.apishim.NsdShimImpl
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.SC_V2
+import com.android.testutils.TestableNetworkAgent
+import com.android.testutils.TestableNetworkCallback
+import com.android.testutils.runAsShell
+import com.android.testutils.tryTest
+import org.junit.After
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertTrue
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import java.net.ServerSocket
@@ -57,12 +83,37 @@
 private const val TIMEOUT_MS = 2000L
 private const val DBG = false
 
+private val nsdShim = NsdShimImpl.newInstance()
+
 @AppModeFull(reason = "Socket cannot bind in instant app mode")
 @RunWith(AndroidJUnit4::class)
 class NsdManagerTest {
+    // NsdManager is not updatable before S, so tests do not need to be backwards compatible
+    @get:Rule
+    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = SC_V2)
+
     private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
     private val nsdManager by lazy { context.getSystemService(NsdManager::class.java) }
+
+    private val cm by lazy { context.getSystemService(ConnectivityManager::class.java) }
     private val serviceName = "NsdTest%09d".format(Random().nextInt(1_000_000_000))
+    private val handlerThread = HandlerThread(NsdManagerTest::class.java.simpleName)
+
+    private lateinit var testNetwork1: TestTapNetwork
+    private lateinit var testNetwork2: TestTapNetwork
+
+    private class TestTapNetwork(
+        val iface: TestNetworkInterface,
+        val requestCb: NetworkCallback,
+        val agent: TestableNetworkAgent,
+        val network: Network
+    ) {
+        fun close(cm: ConnectivityManager) {
+            cm.unregisterNetworkCallback(requestCb)
+            agent.unregister()
+            iface.fileDescriptor.close()
+        }
+    }
 
     private interface NsdEvent
     private open class NsdRecord<T : NsdEvent> private constructor(
@@ -163,9 +214,14 @@
             add(ServiceLost(si))
         }
 
-        fun waitForServiceDiscovered(serviceName: String): NsdServiceInfo {
+        fun waitForServiceDiscovered(
+            serviceName: String,
+            expectedNetwork: Network? = null
+        ): NsdServiceInfo {
             return expectCallbackEventually<ServiceFound> {
-                it.serviceInfo.serviceName == serviceName
+                it.serviceInfo.serviceName == serviceName &&
+                        (expectedNetwork == null ||
+                                expectedNetwork == nsdShim.getNetwork(it.serviceInfo))
             }.serviceInfo
         }
     }
@@ -188,6 +244,58 @@
         }
     }
 
+    @Before
+    fun setUp() {
+        handlerThread.start()
+
+        runAsShell(MANAGE_TEST_NETWORKS) {
+            testNetwork1 = createTestNetwork()
+            testNetwork2 = createTestNetwork()
+        }
+    }
+
+    private fun createTestNetwork(): TestTapNetwork {
+        val tnm = context.getSystemService(TestNetworkManager::class.java)
+        val iface = tnm.createTapInterface()
+        val cb = TestableNetworkCallback()
+        val testNetworkSpecifier = TestNetworkSpecifier(iface.interfaceName)
+        cm.requestNetwork(NetworkRequest.Builder()
+                .removeCapability(NET_CAPABILITY_TRUSTED)
+                .addTransportType(TRANSPORT_TEST)
+                .setNetworkSpecifier(testNetworkSpecifier)
+                .build(), cb)
+        val agent = registerTestNetworkAgent(iface.interfaceName)
+        val network = agent.network ?: fail("Registered agent should have a network")
+        // The network has no INTERNET capability, so will be marked validated immediately
+        cb.expectAvailableThenValidatedCallbacks(network)
+        return TestTapNetwork(iface, cb, agent, network)
+    }
+
+    private fun registerTestNetworkAgent(ifaceName: String): TestableNetworkAgent {
+        val agent = TestableNetworkAgent(context, handlerThread.looper,
+                NetworkCapabilities().apply {
+                    removeCapability(NET_CAPABILITY_TRUSTED)
+                    addTransportType(TRANSPORT_TEST)
+                    setNetworkSpecifier(TestNetworkSpecifier(ifaceName))
+                },
+                LinkProperties().apply {
+                    interfaceName = ifaceName
+                },
+                NetworkAgentConfig.Builder().build())
+        agent.register()
+        agent.markConnected()
+        return agent
+    }
+
+    @After
+    fun tearDown() {
+        runAsShell(MANAGE_TEST_NETWORKS) {
+            testNetwork1.close(cm)
+            testNetwork2.close(cm)
+        }
+        handlerThread.quitSafely()
+    }
+
     @Test
     fun testNsdManager() {
         val si = NsdServiceInfo()
@@ -298,6 +406,149 @@
         registrationRecord2.expectCallback<ServiceUnregistered>()
     }
 
+    @Test
+    fun testNsdManager_DiscoverOnNetwork() {
+        // This tests requires shims supporting T+ APIs (discovering on specific network)
+        assumeTrue(ConstantsShim.VERSION > SC_V2)
+
+        val si = NsdServiceInfo()
+        si.serviceType = SERVICE_TYPE
+        si.serviceName = this.serviceName
+        si.port = 12345 // Test won't try to connect so port does not matter
+
+        val registrationRecord = NsdRegistrationRecord()
+        val registeredInfo = registerService(registrationRecord, si)
+
+        tryTest {
+            val discoveryRecord = NsdDiscoveryRecord()
+            nsdShim.discoverServices(nsdManager, SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
+                    testNetwork1.network, discoveryRecord)
+
+            val foundInfo = discoveryRecord.waitForServiceDiscovered(
+                    serviceName, testNetwork1.network)
+            assertEquals(testNetwork1.network, nsdShim.getNetwork(foundInfo))
+
+            // Rewind to ensure the service is not found on the other interface
+            discoveryRecord.nextEvents.rewind(0)
+            assertNull(discoveryRecord.nextEvents.poll(timeoutMs = 100L) {
+                it is ServiceFound &&
+                        it.serviceInfo.serviceName == registeredInfo.serviceName &&
+                        nsdShim.getNetwork(it.serviceInfo) != testNetwork1.network
+            }, "The service should not be found on this network")
+        } cleanup {
+            nsdManager.unregisterService(registrationRecord)
+        }
+    }
+
+    @Test
+    fun testNsdManager_DiscoverWithNetworkRequest() {
+        // This tests requires shims supporting T+ APIs (discovering on network request)
+        assumeTrue(ConstantsShim.VERSION > SC_V2)
+
+        val si = NsdServiceInfo()
+        si.serviceType = SERVICE_TYPE
+        si.serviceName = this.serviceName
+        si.port = 12345 // Test won't try to connect so port does not matter
+
+        val registrationRecord = NsdRegistrationRecord()
+        val registeredInfo1 = registerService(registrationRecord, si)
+        val discoveryRecord = NsdDiscoveryRecord()
+
+        tryTest {
+            val specifier = TestNetworkSpecifier(testNetwork1.iface.interfaceName)
+            nsdShim.discoverServices(nsdManager, SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
+                    NetworkRequest.Builder()
+                            .removeCapability(NET_CAPABILITY_TRUSTED)
+                            .addTransportType(TRANSPORT_TEST)
+                            .setNetworkSpecifier(specifier)
+                            .build(),
+                    discoveryRecord)
+
+            val discoveryStarted = discoveryRecord.expectCallback<DiscoveryStarted>()
+            assertEquals(SERVICE_TYPE, discoveryStarted.serviceType)
+
+            val serviceDiscovered = discoveryRecord.expectCallback<ServiceFound>()
+            assertEquals(registeredInfo1.serviceName, serviceDiscovered.serviceInfo.serviceName)
+            assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceDiscovered.serviceInfo))
+
+            // Unregister, then register the service back: it should be lost and found again
+            nsdManager.unregisterService(registrationRecord)
+            val serviceLost1 = discoveryRecord.expectCallback<ServiceLost>()
+            assertEquals(registeredInfo1.serviceName, serviceLost1.serviceInfo.serviceName)
+            assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceLost1.serviceInfo))
+
+            registrationRecord.expectCallback<ServiceUnregistered>()
+            val registeredInfo2 = registerService(registrationRecord, si)
+            val serviceDiscovered2 = discoveryRecord.expectCallback<ServiceFound>()
+            assertEquals(registeredInfo2.serviceName, serviceDiscovered2.serviceInfo.serviceName)
+            assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceDiscovered2.serviceInfo))
+
+            // Teardown, then bring back up a network on the test interface: the service should
+            // go away, then come back
+            testNetwork1.agent.unregister()
+            val serviceLost = discoveryRecord.expectCallback<ServiceLost>()
+            assertEquals(registeredInfo2.serviceName, serviceLost.serviceInfo.serviceName)
+            assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceLost.serviceInfo))
+
+            val newAgent = runAsShell(MANAGE_TEST_NETWORKS) {
+                registerTestNetworkAgent(testNetwork1.iface.interfaceName)
+            }
+            val newNetwork = newAgent.network ?: fail("Registered agent should have a network")
+            val serviceDiscovered3 = discoveryRecord.expectCallback<ServiceFound>()
+            assertEquals(registeredInfo2.serviceName, serviceDiscovered3.serviceInfo.serviceName)
+            assertEquals(newNetwork, nsdShim.getNetwork(serviceDiscovered3.serviceInfo))
+        } cleanupStep {
+            nsdManager.stopServiceDiscovery(discoveryRecord)
+            discoveryRecord.expectCallback<DiscoveryStopped>()
+        } cleanup {
+            nsdManager.unregisterService(registrationRecord)
+        }
+    }
+
+    @Test
+    fun testNsdManager_ResolveOnNetwork() {
+        // This tests requires shims supporting T+ APIs (NsdServiceInfo.network)
+        assumeTrue(ConstantsShim.VERSION > SC_V2)
+
+        val si = NsdServiceInfo()
+        si.serviceType = SERVICE_TYPE
+        si.serviceName = this.serviceName
+        si.port = 12345 // Test won't try to connect so port does not matter
+
+        val registrationRecord = NsdRegistrationRecord()
+        val registeredInfo = registerService(registrationRecord, si)
+        tryTest {
+            val resolveRecord = NsdResolveRecord()
+
+            val discoveryRecord = NsdDiscoveryRecord()
+            nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryRecord)
+
+            val foundInfo1 = discoveryRecord.waitForServiceDiscovered(
+                    serviceName, testNetwork1.network)
+            assertEquals(testNetwork1.network, nsdShim.getNetwork(foundInfo1))
+            // Rewind as the service could be found on each interface in any order
+            discoveryRecord.nextEvents.rewind(0)
+            val foundInfo2 = discoveryRecord.waitForServiceDiscovered(
+                    serviceName, testNetwork2.network)
+            assertEquals(testNetwork2.network, nsdShim.getNetwork(foundInfo2))
+
+            nsdManager.resolveService(foundInfo1, resolveRecord)
+            val cb = resolveRecord.expectCallback<ServiceResolved>()
+            cb.serviceInfo.let {
+                // Resolved service type has leading dot
+                assertEquals(".$SERVICE_TYPE", it.serviceType)
+                assertEquals(registeredInfo.serviceName, it.serviceName)
+                assertEquals(si.port, it.port)
+                assertEquals(testNetwork1.network, nsdShim.getNetwork(it))
+            }
+            // TODO: check that MDNS packets are sent only on testNetwork1.
+        } cleanupStep {
+            nsdManager.unregisterService(registrationRecord)
+        } cleanup {
+            registrationRecord.expectCallback<ServiceUnregistered>()
+        }
+    }
+
     /**
      * Register a service and return its registration record.
      */
diff --git a/tests/deflake/Android.bp b/tests/deflake/Android.bp
index 8205f1c..b3d0363 100644
--- a/tests/deflake/Android.bp
+++ b/tests/deflake/Android.bp
@@ -21,7 +21,7 @@
 
 // FrameworksNetDeflakeTest depends on FrameworksNetTests so it should be disabled
 // if FrameworksNetTests is disabled.
-enable_frameworks_net_deflake_test = true
+enable_frameworks_net_deflake_test = false
 // Placeholder
 // This is a placeholder comment to minimize merge conflicts, as enable_frameworks_net_deflake_test
 // may have different values depending on the branch
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 25b391a..fe0210c 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -13,7 +13,7 @@
 // Whether to enable the FrameworksNetTests. Set to false in the branches that might have older
 // frameworks/base since FrameworksNetTests includes the test for classes that are not in
 // connectivity module.
-enable_frameworks_net_tests = true
+enable_frameworks_net_tests = false
 // Placeholder
 // This is a placeholder comment to minimize merge conflicts, as enable_frameworks_net_tests
 // may have different values depending on the branch
diff --git a/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java b/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java
index ca8cf07..e5e7ebc 100644
--- a/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java
+++ b/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.net.Network;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -123,6 +124,7 @@
         fullInfo.setServiceType("_kitten._tcp");
         fullInfo.setPort(4242);
         fullInfo.setHost(LOCALHOST);
+        fullInfo.setNetwork(new Network(123));
         checkParcelable(fullInfo);
 
         NsdServiceInfo noHostInfo = new NsdServiceInfo();
@@ -172,6 +174,7 @@
         assertEquals(original.getServiceType(), result.getServiceType());
         assertEquals(original.getHost(), result.getHost());
         assertTrue(original.getPort() == result.getPort());
+        assertEquals(original.getNetwork(), result.getNetwork());
 
         // Assert equality of attribute map.
         Map<String, byte[]> originalMap = original.getAttributes();
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 6d1d765..5086943 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -218,14 +218,14 @@
         client.discoverServices("a_type", PROTOCOL, listener2);
         waitForIdle();
         verify(mDaemon, times(1)).maybeStart();
-        verifyDaemonCommand("discover 3 a_type");
+        verifyDaemonCommand("discover 3 a_type 0");
 
         // Client resolve request
         NsdManager.ResolveListener listener3 = mock(NsdManager.ResolveListener.class);
         client.resolveService(request, listener3);
         waitForIdle();
         verify(mDaemon, times(1)).maybeStart();
-        verifyDaemonCommand("resolve 4 a_name a_type local.");
+        verifyDaemonCommand("resolve 4 a_name a_type local. 0");
 
         // Client disconnects, stop the daemon after CLEANUP_DELAY_MS.
         deathRecipient.binderDied();
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index fd9aefa..33c0868 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -17,6 +17,9 @@
 package com.android.server.connectivity;
 
 import static android.Manifest.permission.BIND_VPN_SERVICE;
+import static android.Manifest.permission.CONTROL_VPN;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.pm.UserInfo.FLAG_ADMIN;
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
 import static android.content.pm.UserInfo.FLAG_PRIMARY;
@@ -26,6 +29,9 @@
 import static android.net.INetd.IF_STATE_UP;
 import static android.os.UserHandle.PER_USER_RANGE;
 
+import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
+import static com.android.testutils.MiscAsserts.assertThrows;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -259,6 +265,10 @@
                         IpSecManager.Status.OK, TEST_TUNNEL_RESOURCE_ID, TEST_IFACE_NAME);
         when(mIpSecService.createTunnelInterface(any(), any(), any(), any(), any()))
                 .thenReturn(tunnelResp);
+        // The unit test should know what kind of permission it needs and set the permission by
+        // itself, so set the default value of Context#checkCallingOrSelfPermission to
+        // PERMISSION_DENIED.
+        doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any());
     }
 
     private <T> void mockService(Class<T> clazz, String name, T service) {
@@ -511,6 +521,7 @@
 
     @Test
     public void testLockdownRuleReversibility() throws Exception {
+        doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
         final Vpn vpn = createVpn(primaryUser.id);
         final UidRangeParcel[] entireUser = {
             new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())
@@ -538,6 +549,27 @@
     }
 
     @Test
+    public void testPrepare_throwSecurityExceptionWhenGivenPackageDoesNotBelongToTheCaller()
+            throws Exception {
+        assumeTrue(isAtLeastT());
+        final Vpn vpn = createVpnAndSetupUidChecks();
+        assertThrows(SecurityException.class,
+                () -> vpn.prepare("com.not.vpn.owner", null, VpnManager.TYPE_VPN_SERVICE));
+        assertThrows(SecurityException.class,
+                () -> vpn.prepare(null, "com.not.vpn.owner", VpnManager.TYPE_VPN_SERVICE));
+        assertThrows(SecurityException.class,
+                () -> vpn.prepare("com.not.vpn.owner1", "com.not.vpn.owner2",
+                        VpnManager.TYPE_VPN_SERVICE));
+    }
+
+    @Test
+    public void testPrepare_bothOldPackageAndNewPackageAreNull() throws Exception {
+        final Vpn vpn = createVpnAndSetupUidChecks();
+        assertTrue(vpn.prepare(null, null, VpnManager.TYPE_VPN_SERVICE));
+
+    }
+
+    @Test
     public void testIsAlwaysOnPackageSupported() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);