Merge "Increase the timeout waiting for the test app's network status." into main
diff --git a/Cronet/tools/import/copy.bara.sky b/Cronet/tools/import/copy.bara.sky
index 5372a4d..4a92a13 100644
--- a/Cronet/tools/import/copy.bara.sky
+++ b/Cronet/tools/import/copy.bara.sky
@@ -71,6 +71,8 @@
         "base/third_party/nspr/**",
         "base/third_party/superfasthash/**",
         "base/third_party/valgrind/**",
+        # Those are temporarily needed until Chromium finish the migration
+        # of libc++[abi]
         "buildtools/third_party/libc++/**",
         "buildtools/third_party/libc++abi/**",
         # Note: Only used for tests.
@@ -85,8 +87,13 @@
         # Note: Only used for tests.
         "third_party/ced/**",
         # Note: Only used for tests.
+        "third_party/google_benchmark/**",
+        # Note: Only used for tests.
         "third_party/googletest/**",
         "third_party/icu/**",
+        "third_party/jni_zero/**",
+        "third_party/libc++/**",
+        "third_party/libc++abi/**",
         "third_party/libevent/**",
         # Note: Only used for tests.
         "third_party/libxml/**",
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index fe70820..747cc20 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -22,9 +22,7 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
 import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
-import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
 
-import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME;
 import static com.android.networkstack.apishim.ConstantsShim.KEY_CARRIER_SUPPORTS_TETHERING_BOOL;
 
 import android.content.ContentResolver;
@@ -179,16 +177,30 @@
      */
     @VisibleForTesting
     public static class Dependencies {
-        boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
-                @NonNull String name, @NonNull String moduleName, boolean defaultEnabled) {
-            return DeviceConfigUtils.isTetheringFeatureEnabled(context, namespace, name,
-                    moduleName, defaultEnabled);
+        boolean isFeatureEnabled(@NonNull Context context, @NonNull String name) {
+            return DeviceConfigUtils.isTetheringFeatureEnabled(context, name);
         }
 
         boolean getDeviceConfigBoolean(@NonNull String namespace, @NonNull String name,
                 boolean defaultValue) {
             return DeviceConfig.getBoolean(namespace, name, defaultValue);
         }
+
+        /**
+         * TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION is used to force enable the feature on specific
+         * R devices. Just checking the flag value is enough since the flag has been pushed to
+         * enable the feature on the old version and any new binary will always have a version
+         * number newer than the flag.
+         * This flag is wrongly configured in the connectivity namespace so this method reads the
+         * flag value from the connectivity namespace. But the tethering module should use the
+         * tethering namespace. This method can be removed after R EOL.
+         */
+        boolean isTetherForceUpstreamAutomaticFeatureEnabled() {
+            final int flagValue = DeviceConfigUtils.getDeviceConfigPropertyInt(
+                    NAMESPACE_CONNECTIVITY, TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION,
+                    0 /* defaultValue */);
+            return flagValue > 0;
+        }
     }
 
     public TetheringConfiguration(@NonNull Context ctx, @NonNull SharedLog log, int id) {
@@ -237,7 +249,7 @@
         // - S, T: can be enabled/disabled by resource config_tether_upstream_automatic.
         // - U+  : automatic mode only.
         final boolean forceAutomaticUpstream = SdkLevel.isAtLeastU() || (!SdkLevel.isAtLeastS()
-                && isConnectivityFeatureEnabled(ctx, TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION));
+                && mDeps.isTetherForceUpstreamAutomaticFeatureEnabled());
         chooseUpstreamAutomatically = forceAutomaticUpstream || getResourceBoolean(
                 res, R.bool.config_tether_upstream_automatic, false /** defaultValue */);
         preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
@@ -607,32 +619,13 @@
 
     private boolean shouldEnableWearTethering(Context context) {
         return SdkLevel.isAtLeastT()
-            && isTetheringFeatureEnabled(context, TETHER_ENABLE_WEAR_TETHERING);
+            && mDeps.isFeatureEnabled(context, TETHER_ENABLE_WEAR_TETHERING);
     }
 
     private boolean getDeviceConfigBoolean(final String name, final boolean defaultValue) {
         return mDeps.getDeviceConfigBoolean(NAMESPACE_CONNECTIVITY, name, defaultValue);
     }
 
-    /**
-     * This is deprecated because connectivity namespace already be used for NetworkStack mainline
-     * module. Tethering should use its own namespace to roll out the feature flag.
-     * @deprecated new caller should use isTetheringFeatureEnabled instead.
-     */
-    @Deprecated
-    private boolean isConnectivityFeatureEnabled(Context ctx, String featureVersionFlag) {
-        return isFeatureEnabled(ctx, NAMESPACE_CONNECTIVITY, featureVersionFlag);
-    }
-
-    private boolean isTetheringFeatureEnabled(Context ctx, String featureVersionFlag) {
-        return isFeatureEnabled(ctx, NAMESPACE_TETHERING, featureVersionFlag);
-    }
-
-    private boolean isFeatureEnabled(Context ctx, String namespace, String featureVersionFlag) {
-        return mDeps.isFeatureEnabled(ctx, namespace, featureVersionFlag, TETHERING_MODULE_NAME,
-                false /* defaultEnabled */);
-    }
-
     private Resources getResources(Context ctx, int subId) {
         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
             return getResourcesForSubIdWrapper(ctx, subId);
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
index 9e287a0..087be26 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
@@ -28,9 +28,8 @@
     FakeTetheringConfiguration(Context ctx, SharedLog log, int id) {
         super(ctx, log, id, new Dependencies() {
             @Override
-            boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
-                    @NonNull String name, @NonNull String moduleName, boolean defaultEnabled) {
-                return defaultEnabled;
+            boolean isFeatureEnabled(@NonNull Context context, @NonNull String name) {
+                return false;
             }
 
             @Override
@@ -38,6 +37,11 @@
                     boolean defaultValue) {
                 return defaultValue;
             }
+
+            @Override
+            boolean isTetherForceUpstreamAutomaticFeatureEnabled() {
+                return false;
+            }
         });
     }
 
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
index 3382af8..aa322dc 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
@@ -155,9 +155,8 @@
         private ArrayMap<String, Boolean> mMockFlags = new ArrayMap<>();
 
         @Override
-        boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
-                @NonNull String name, @NonNull String moduleName, boolean defaultEnabled) {
-            return isMockFlagEnabled(name, defaultEnabled);
+        boolean isFeatureEnabled(@NonNull Context context, @NonNull String name) {
+            return isMockFlagEnabled(name, false /* defaultEnabled */);
         }
 
         @Override
@@ -172,6 +171,12 @@
             return isMockFlagEnabled(name, defaultValue);
         }
 
+        @Override
+        boolean isTetherForceUpstreamAutomaticFeatureEnabled() {
+            return isMockFlagEnabled(TetheringConfiguration.TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION,
+                    false /* defaultEnabled */);
+        }
+
         private boolean isMockFlagEnabled(@NonNull String name, boolean defaultEnabled) {
             final Boolean flag = mMockFlags.getOrDefault(name, defaultEnabled);
             // Value in the map can also be null
diff --git a/framework-t/Android.bp b/framework-t/Android.bp
index 5ae1ef9..9e5ecb4 100644
--- a/framework-t/Android.bp
+++ b/framework-t/Android.bp
@@ -93,6 +93,9 @@
 
 // The filegroup lists files that are necessary for verifying building mdns as a standalone,
 // for use with service-connectivity-mdns-standalone-build-test
+// This filegroup should never be included in anywhere in the module build. It is only used for
+// building service-connectivity-mdns-standalone-build-test target. The files will be renamed by
+// copybara to prevent them from being shadowed by the bootclasspath copies.
 filegroup {
     name: "framework-connectivity-t-mdns-standalone-build-sources",
     srcs: [
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index b9acc48..1250e65 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -26,7 +26,6 @@
 import static android.net.nsd.NsdManager.MDNS_SERVICE_EVENT;
 import static android.net.nsd.NsdManager.RESOLVE_SERVICE_SUCCEEDED;
 import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
-
 import static com.android.modules.utils.build.SdkLevel.isAtLeastU;
 import static com.android.networkstack.apishim.ConstantsShim.REGISTER_NSD_OFFLOAD_ENGINE;
 import static com.android.server.connectivity.mdns.MdnsAdvertiser.AdvertiserMetrics;
@@ -89,6 +88,7 @@
 import com.android.server.connectivity.mdns.ExecutorProvider;
 import com.android.server.connectivity.mdns.MdnsAdvertiser;
 import com.android.server.connectivity.mdns.MdnsDiscoveryManager;
+import com.android.server.connectivity.mdns.MdnsFeatureFlags;
 import com.android.server.connectivity.mdns.MdnsInterfaceSocket;
 import com.android.server.connectivity.mdns.MdnsMultinetworkSocketClient;
 import com.android.server.connectivity.mdns.MdnsSearchOptions;
@@ -1695,8 +1695,11 @@
         mMdnsDiscoveryManager = deps.makeMdnsDiscoveryManager(new ExecutorProvider(),
                 mMdnsSocketClient, LOGGER.forSubComponent("MdnsDiscoveryManager"));
         handler.post(() -> mMdnsSocketClient.setCallback(mMdnsDiscoveryManager));
+        MdnsFeatureFlags flags = new MdnsFeatureFlags.Builder().setIsMdnsOffloadFeatureEnabled(
+                mDeps.isTetheringFeatureNotChickenedOut(
+                        MdnsFeatureFlags.NSD_FORCE_DISABLE_MDNS_OFFLOAD)).build();
         mAdvertiser = deps.makeMdnsAdvertiser(handler.getLooper(), mMdnsSocketProvider,
-                new AdvertiserCallback(), LOGGER.forSubComponent("MdnsAdvertiser"));
+                new AdvertiserCallback(), LOGGER.forSubComponent("MdnsAdvertiser"), flags);
         mClock = deps.makeClock();
     }
 
@@ -1713,8 +1716,7 @@
          */
         public boolean isMdnsDiscoveryManagerEnabled(Context context) {
             return isAtLeastU() || DeviceConfigUtils.isTetheringFeatureEnabled(context,
-                    NAMESPACE_TETHERING, MDNS_DISCOVERY_MANAGER_VERSION,
-                    DeviceConfigUtils.TETHERING_MODULE_NAME, false /* defaultEnabled */);
+                    MDNS_DISCOVERY_MANAGER_VERSION);
         }
 
         /**
@@ -1725,8 +1727,7 @@
          */
         public boolean isMdnsAdvertiserEnabled(Context context) {
             return isAtLeastU() || DeviceConfigUtils.isTetheringFeatureEnabled(context,
-                    NAMESPACE_TETHERING, MDNS_ADVERTISER_VERSION,
-                    DeviceConfigUtils.TETHERING_MODULE_NAME, false /* defaultEnabled */);
+                    MDNS_ADVERTISER_VERSION);
         }
 
         /**
@@ -1743,8 +1744,14 @@
          * @see DeviceConfigUtils#isTetheringFeatureEnabled
          */
         public boolean isFeatureEnabled(Context context, String feature) {
-            return DeviceConfigUtils.isTetheringFeatureEnabled(context, NAMESPACE_TETHERING,
-                    feature, DeviceConfigUtils.TETHERING_MODULE_NAME, false /* defaultEnabled */);
+            return DeviceConfigUtils.isTetheringFeatureEnabled(context, feature);
+        }
+
+        /**
+         * @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut
+         */
+        public boolean isTetheringFeatureNotChickenedOut(String feature) {
+            return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(feature);
         }
 
         /**
@@ -1761,8 +1768,9 @@
          */
         public MdnsAdvertiser makeMdnsAdvertiser(
                 @NonNull Looper looper, @NonNull MdnsSocketProvider socketProvider,
-                @NonNull MdnsAdvertiser.AdvertiserCallback cb, @NonNull SharedLog sharedLog) {
-            return new MdnsAdvertiser(looper, socketProvider, cb, sharedLog);
+                @NonNull MdnsAdvertiser.AdvertiserCallback cb, @NonNull SharedLog sharedLog,
+                MdnsFeatureFlags featureFlags) {
+            return new MdnsAdvertiser(looper, socketProvider, cb, sharedLog, featureFlags);
         }
 
         /**
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java b/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
index 913d233..ce13747 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
@@ -78,6 +78,7 @@
     @NonNull private final SharedLog mSharedLog;
     private final Map<String, List<OffloadServiceInfoWrapper>> mInterfaceOffloadServices =
             new ArrayMap<>();
+    private final MdnsFeatureFlags mMdnsFeatureFlags;
 
     /**
      * Dependencies for {@link MdnsAdvertiser}, useful for testing.
@@ -140,22 +141,21 @@
                 mSharedLog.wtf("Register succeeded for unknown registration");
                 return;
             }
+            if (mMdnsFeatureFlags.mIsMdnsOffloadFeatureEnabled) {
+                final String interfaceName = advertiser.getSocketInterfaceName();
+                final List<OffloadServiceInfoWrapper> existingOffloadServiceInfoWrappers =
+                        mInterfaceOffloadServices.computeIfAbsent(interfaceName,
+                                k -> new ArrayList<>());
+                // Remove existing offload services from cache for update.
+                existingOffloadServiceInfoWrappers.removeIf(item -> item.mServiceId == serviceId);
 
-            final String interfaceName = advertiser.getSocketInterfaceName();
-            final List<OffloadServiceInfoWrapper> existingOffloadServiceInfoWrappers =
-                    mInterfaceOffloadServices.computeIfAbsent(
-                            interfaceName, k -> new ArrayList<>());
-            // Remove existing offload services from cache for update.
-            existingOffloadServiceInfoWrappers.removeIf(item -> item.mServiceId == serviceId);
-
-            byte[] rawOffloadPacket = advertiser.getRawOffloadPayload(serviceId);
-            final OffloadServiceInfoWrapper newOffloadServiceInfoWrapper = createOffloadService(
-                    serviceId,
-                    registration,
-                    rawOffloadPacket);
-            existingOffloadServiceInfoWrappers.add(newOffloadServiceInfoWrapper);
-            mCb.onOffloadStartOrUpdate(interfaceName,
-                    newOffloadServiceInfoWrapper.mOffloadServiceInfo);
+                byte[] rawOffloadPacket = advertiser.getRawOffloadPayload(serviceId);
+                final OffloadServiceInfoWrapper newOffloadServiceInfoWrapper = createOffloadService(
+                        serviceId, registration, rawOffloadPacket);
+                existingOffloadServiceInfoWrappers.add(newOffloadServiceInfoWrapper);
+                mCb.onOffloadStartOrUpdate(interfaceName,
+                        newOffloadServiceInfoWrapper.mOffloadServiceInfo);
+            }
 
             // Wait for all current interfaces to be done probing before notifying of success.
             if (any(mAllAdvertisers, (k, a) -> a.isProbing(serviceId))) return;
@@ -188,7 +188,9 @@
                     if (!a.maybeRestartProbingForConflict(serviceId)) {
                         return;
                     }
-                    maybeSendOffloadStop(a.getSocketInterfaceName(), serviceId);
+                    if (mMdnsFeatureFlags.mIsMdnsOffloadFeatureEnabled) {
+                        maybeSendOffloadStop(a.getSocketInterfaceName(), serviceId);
+                    }
                 });
                 return;
             }
@@ -280,12 +282,12 @@
          */
         boolean onAdvertiserDestroyed(@NonNull MdnsInterfaceSocket socket) {
             final MdnsInterfaceAdvertiser removedAdvertiser = mAdvertisers.remove(socket);
-            if (removedAdvertiser != null) {
+            if (mMdnsFeatureFlags.mIsMdnsOffloadFeatureEnabled && removedAdvertiser != null) {
                 final String interfaceName = removedAdvertiser.getSocketInterfaceName();
-                // If the interface is destroyed, stop all hardware offloading on that interface.
+                // If the interface is destroyed, stop all hardware offloading on that
+                // interface.
                 final List<OffloadServiceInfoWrapper> offloadServiceInfoWrappers =
-                        mInterfaceOffloadServices.remove(
-                                interfaceName);
+                        mInterfaceOffloadServices.remove(interfaceName);
                 if (offloadServiceInfoWrappers != null) {
                     for (OffloadServiceInfoWrapper offloadServiceInfoWrapper :
                             offloadServiceInfoWrappers) {
@@ -359,7 +361,9 @@
                 final MdnsInterfaceAdvertiser advertiser = mAdvertisers.valueAt(i);
                 advertiser.removeService(id);
 
-                maybeSendOffloadStop(advertiser.getSocketInterfaceName(), id);
+                if (mMdnsFeatureFlags.mIsMdnsOffloadFeatureEnabled) {
+                    maybeSendOffloadStop(advertiser.getSocketInterfaceName(), id);
+                }
             }
         }
 
@@ -419,25 +423,28 @@
                 return;
             }
             advertiser.updateAddresses(addresses);
-            // Update address should trigger offload packet update.
-            final String interfaceName = advertiser.getSocketInterfaceName();
-            final List<OffloadServiceInfoWrapper> existingOffloadServiceInfoWrappers =
-                    mInterfaceOffloadServices.get(interfaceName);
-            if (existingOffloadServiceInfoWrappers == null) {
-                return;
+
+            if (mMdnsFeatureFlags.mIsMdnsOffloadFeatureEnabled) {
+                // Update address should trigger offload packet update.
+                final String interfaceName = advertiser.getSocketInterfaceName();
+                final List<OffloadServiceInfoWrapper> existingOffloadServiceInfoWrappers =
+                        mInterfaceOffloadServices.get(interfaceName);
+                if (existingOffloadServiceInfoWrappers == null) {
+                    return;
+                }
+                final List<OffloadServiceInfoWrapper> updatedOffloadServiceInfoWrappers =
+                        new ArrayList<>(existingOffloadServiceInfoWrappers.size());
+                for (OffloadServiceInfoWrapper oldWrapper : existingOffloadServiceInfoWrappers) {
+                    OffloadServiceInfoWrapper newWrapper = new OffloadServiceInfoWrapper(
+                            oldWrapper.mServiceId,
+                            oldWrapper.mOffloadServiceInfo.withOffloadPayload(
+                                    advertiser.getRawOffloadPayload(oldWrapper.mServiceId))
+                    );
+                    updatedOffloadServiceInfoWrappers.add(newWrapper);
+                    mCb.onOffloadStartOrUpdate(interfaceName, newWrapper.mOffloadServiceInfo);
+                }
+                mInterfaceOffloadServices.put(interfaceName, updatedOffloadServiceInfoWrappers);
             }
-            final List<OffloadServiceInfoWrapper> updatedOffloadServiceInfoWrappers =
-                    new ArrayList<>(existingOffloadServiceInfoWrappers.size());
-            for (OffloadServiceInfoWrapper oldWrapper : existingOffloadServiceInfoWrappers) {
-                OffloadServiceInfoWrapper newWrapper = new OffloadServiceInfoWrapper(
-                        oldWrapper.mServiceId,
-                        oldWrapper.mOffloadServiceInfo.withOffloadPayload(
-                                advertiser.getRawOffloadPayload(oldWrapper.mServiceId))
-                );
-                updatedOffloadServiceInfoWrappers.add(newWrapper);
-                mCb.onOffloadStartOrUpdate(interfaceName, newWrapper.mOffloadServiceInfo);
-            }
-            mInterfaceOffloadServices.put(interfaceName, updatedOffloadServiceInfoWrappers);
         }
     }
 
@@ -595,20 +602,22 @@
     }
 
     public MdnsAdvertiser(@NonNull Looper looper, @NonNull MdnsSocketProvider socketProvider,
-            @NonNull AdvertiserCallback cb, @NonNull SharedLog sharedLog) {
-        this(looper, socketProvider, cb, new Dependencies(), sharedLog);
+            @NonNull AdvertiserCallback cb, @NonNull SharedLog sharedLog,
+            @NonNull MdnsFeatureFlags mDnsFeatureFlags) {
+        this(looper, socketProvider, cb, new Dependencies(), sharedLog, mDnsFeatureFlags);
     }
 
     @VisibleForTesting
     MdnsAdvertiser(@NonNull Looper looper, @NonNull MdnsSocketProvider socketProvider,
             @NonNull AdvertiserCallback cb, @NonNull Dependencies deps,
-            @NonNull SharedLog sharedLog) {
+            @NonNull SharedLog sharedLog, @NonNull MdnsFeatureFlags mDnsFeatureFlags) {
         mLooper = looper;
         mCb = cb;
         mSocketProvider = socketProvider;
         mDeps = deps;
         mDeviceHostName = deps.generateHostname();
         mSharedLog = sharedLog;
+        mMdnsFeatureFlags = mDnsFeatureFlags;
     }
 
     private void checkThread() {
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsFeatureFlags.java b/service-t/src/com/android/server/connectivity/mdns/MdnsFeatureFlags.java
new file mode 100644
index 0000000..9840409
--- /dev/null
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsFeatureFlags.java
@@ -0,0 +1,71 @@
+/*
+ * 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.connectivity.mdns;
+
+/**
+ * The class that contains mDNS feature flags;
+ */
+public class MdnsFeatureFlags {
+    /**
+     * The feature flag for control whether the  mDNS offload is enabled or not.
+     */
+    public static final String NSD_FORCE_DISABLE_MDNS_OFFLOAD = "nsd_force_disable_mdns_offload";
+
+    // Flag for offload feature
+    public final boolean mIsMdnsOffloadFeatureEnabled;
+
+    /**
+     * The constructor for {@link MdnsFeatureFlags}.
+     */
+    public MdnsFeatureFlags(boolean isOffloadFeatureEnabled) {
+        mIsMdnsOffloadFeatureEnabled = isOffloadFeatureEnabled;
+    }
+
+
+    /** Returns a {@link Builder} for {@link MdnsFeatureFlags}. */
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /** A builder to create {@link MdnsFeatureFlags}. */
+    public static final class Builder {
+
+        private boolean mIsMdnsOffloadFeatureEnabled;
+
+        /**
+         * The constructor for {@link Builder}.
+         */
+        public Builder() {
+            mIsMdnsOffloadFeatureEnabled = false;
+        }
+
+        /**
+         * Set if the mDNS offload  feature is enabled.
+         */
+        public Builder setIsMdnsOffloadFeatureEnabled(boolean isMdnsOffloadFeatureEnabled) {
+            mIsMdnsOffloadFeatureEnabled = isMdnsOffloadFeatureEnabled;
+            return this;
+        }
+
+        /**
+         * Builds a {@link MdnsFeatureFlags} with the arguments supplied to this builder.
+         */
+        public MdnsFeatureFlags build() {
+            return new MdnsFeatureFlags(mIsMdnsOffloadFeatureEnabled);
+        }
+
+    }
+}
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java b/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
index 1fb4d90..f532372 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
@@ -399,7 +399,9 @@
                 r -> new MdnsPointerRecord(
                         r.record.getName(),
                         0L /* receiptTimeMillis */,
-                        true /* cacheFlush */,
+                        // RFC6762#10.1, the cache flush bit should be false for existing
+                        // announcement. Otherwise, the record will be deleted immediately.
+                        false /* cacheFlush */,
                         0L /* ttlMillis */,
                         r.record.getPointer()));
 
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 60523dd..6770a8f 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -93,12 +93,10 @@
 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY;
 import static android.os.Process.INVALID_UID;
 import static android.os.Process.VPN_UID;
-import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
 import static android.system.OsConstants.ETH_P_ALL;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
 
-import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME;
 import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired;
 import static com.android.net.module.util.PermissionUtils.checkAnyPermissionOf;
 import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf;
@@ -1424,8 +1422,7 @@
          * @see DeviceConfigUtils#isTetheringFeatureEnabled
          */
         public boolean isFeatureEnabled(Context context, String name) {
-            return DeviceConfigUtils.isTetheringFeatureEnabled(context, NAMESPACE_TETHERING, name,
-                    TETHERING_MODULE_NAME, false /* defaultValue */);
+            return DeviceConfigUtils.isTetheringFeatureEnabled(context, name);
         }
 
         /**
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 44ed02a..d32a9c0 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -35,17 +35,14 @@
 import static android.net.nsd.NsdManager.FAILURE_BAD_PARAMETERS;
 import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
 import static android.net.nsd.NsdManager.FAILURE_OPERATION_NOT_RUNNING;
-
 import static com.android.networkstack.apishim.api33.ConstantsShim.REGISTER_NSD_OFFLOAD_ENGINE;
 import static com.android.server.NsdService.DEFAULT_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF;
 import static com.android.server.NsdService.MdnsListener;
 import static com.android.server.NsdService.NO_TRANSACTION;
 import static com.android.server.NsdService.parseTypeAndSubtype;
 import static com.android.testutils.ContextUtils.mockService;
-
 import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
 import static libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -229,7 +226,7 @@
         doReturn(mSocketProvider).when(mDeps).makeMdnsSocketProvider(any(), any(), any(), any());
         doReturn(DEFAULT_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF).when(mDeps).getDeviceConfigInt(
                 eq(NsdService.MDNS_CONFIG_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF), anyInt());
-        doReturn(mAdvertiser).when(mDeps).makeMdnsAdvertiser(any(), any(), any(), any());
+        doReturn(mAdvertiser).when(mDeps).makeMdnsAdvertiser(any(), any(), any(), any(), any());
         doReturn(mMetrics).when(mDeps).makeNetworkNsdReportedMetrics(anyBoolean(), anyInt());
         doReturn(mClock).when(mDeps).makeClock();
         doReturn(TEST_TIME_MS).when(mClock).elapsedRealtime();
@@ -1289,7 +1286,7 @@
         // final String serviceTypeWithLocalDomain = SERVICE_TYPE + ".local";
         final ArgumentCaptor<MdnsAdvertiser.AdvertiserCallback> cbCaptor =
                 ArgumentCaptor.forClass(MdnsAdvertiser.AdvertiserCallback.class);
-        verify(mDeps).makeMdnsAdvertiser(any(), any(), cbCaptor.capture(), any());
+        verify(mDeps).makeMdnsAdvertiser(any(), any(), cbCaptor.capture(), any(), any());
 
         final NsdServiceInfo regInfo = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
         regInfo.setHost(parseNumericAddress("192.0.2.123"));
@@ -1339,7 +1336,7 @@
         // final String serviceTypeWithLocalDomain = SERVICE_TYPE + ".local";
         final ArgumentCaptor<MdnsAdvertiser.AdvertiserCallback> cbCaptor =
                 ArgumentCaptor.forClass(MdnsAdvertiser.AdvertiserCallback.class);
-        verify(mDeps).makeMdnsAdvertiser(any(), any(), cbCaptor.capture(), any());
+        verify(mDeps).makeMdnsAdvertiser(any(), any(), cbCaptor.capture(), any(), any());
 
         final NsdServiceInfo regInfo = new NsdServiceInfo(SERVICE_NAME, "invalid_type");
         regInfo.setHost(parseNumericAddress("192.0.2.123"));
@@ -1365,7 +1362,7 @@
         // final String serviceTypeWithLocalDomain = SERVICE_TYPE + ".local";
         final ArgumentCaptor<MdnsAdvertiser.AdvertiserCallback> cbCaptor =
                 ArgumentCaptor.forClass(MdnsAdvertiser.AdvertiserCallback.class);
-        verify(mDeps).makeMdnsAdvertiser(any(), any(), cbCaptor.capture(), any());
+        verify(mDeps).makeMdnsAdvertiser(any(), any(), cbCaptor.capture(), any(), any());
 
         final NsdServiceInfo regInfo = new NsdServiceInfo("a".repeat(70), SERVICE_TYPE);
         regInfo.setHost(parseNumericAddress("192.0.2.123"));
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt
index 8b10e0b..8eace1c 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt
@@ -146,6 +146,7 @@
     private val mockInterfaceAdvertiser1 = mock(MdnsInterfaceAdvertiser::class.java)
     private val mockInterfaceAdvertiser2 = mock(MdnsInterfaceAdvertiser::class.java)
     private val mockDeps = mock(MdnsAdvertiser.Dependencies::class.java)
+    private val flags = MdnsFeatureFlags.newBuilder().setIsMdnsOffloadFeatureEnabled(true).build()
 
     @Before
     fun setUp() {
@@ -183,7 +184,8 @@
 
     @Test
     fun testAddService_OneNetwork() {
-        val advertiser = MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog)
+        val advertiser =
+            MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog, flags)
         postSync { advertiser.addService(SERVICE_ID_1, SERVICE_1, null /* subtype */) }
 
         val socketCbCaptor = ArgumentCaptor.forClass(SocketCallback::class.java)
@@ -242,7 +244,8 @@
 
     @Test
     fun testAddService_AllNetworks() {
-        val advertiser = MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog)
+        val advertiser =
+            MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog, flags)
         postSync { advertiser.addService(SERVICE_ID_1, ALL_NETWORKS_SERVICE, TEST_SUBTYPE) }
 
         val socketCbCaptor = ArgumentCaptor.forClass(SocketCallback::class.java)
@@ -312,7 +315,8 @@
 
     @Test
     fun testAddService_Conflicts() {
-        val advertiser = MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog)
+        val advertiser =
+            MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog, flags)
         postSync { advertiser.addService(SERVICE_ID_1, SERVICE_1, null /* subtype */) }
 
         val oneNetSocketCbCaptor = ArgumentCaptor.forClass(SocketCallback::class.java)
@@ -396,7 +400,8 @@
 
     @Test
     fun testRemoveService_whenAllServiceRemoved_thenUpdateHostName() {
-        val advertiser = MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog)
+        val advertiser =
+            MdnsAdvertiser(thread.looper, socketProvider, cb, mockDeps, sharedlog, flags)
         verify(mockDeps, times(1)).generateHostname()
         postSync { advertiser.addService(SERVICE_ID_1, SERVICE_1, null /* subtype */) }
         postSync { advertiser.removeService(SERVICE_ID_1) }
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
index af47b1c..88fb66a 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
@@ -182,7 +182,7 @@
                 MdnsPointerRecord(
                         arrayOf("_testservice", "_tcp", "local"),
                         0L /* receiptTimeMillis */,
-                        true /* cacheFlush */,
+                        false /* cacheFlush */,
                         0L /* ttlMillis */,
                         arrayOf("MyTestService", "_testservice", "_tcp", "local"))
         ), packet.answers)
@@ -211,13 +211,13 @@
                 MdnsPointerRecord(
                         arrayOf("_testservice", "_tcp", "local"),
                         0L /* receiptTimeMillis */,
-                        true /* cacheFlush */,
+                        false /* cacheFlush */,
                         0L /* ttlMillis */,
                         arrayOf("MyTestService", "_testservice", "_tcp", "local")),
                 MdnsPointerRecord(
                         arrayOf("_subtype", "_sub", "_testservice", "_tcp", "local"),
                         0L /* receiptTimeMillis */,
-                        true /* cacheFlush */,
+                        false /* cacheFlush */,
                         0L /* ttlMillis */,
                         arrayOf("MyTestService", "_testservice", "_tcp", "local")),
         ), packet.answers)