Add Chicken bit for the mDNS offload feature
Bug: 297482971
Test: TH
Change-Id: I6f2cdd066d9047b113ff80211cf6d4c6fa605104
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index b9acc48..6ac8ec0 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();
}
@@ -1748,6 +1751,13 @@
}
/**
+ * @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut
+ */
+ public boolean isTetheringFeatureNotChickenedOut(String feature) {
+ return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(feature);
+ }
+
+ /**
* @see MdnsDiscoveryManager
*/
public MdnsDiscoveryManager makeMdnsDiscoveryManager(
@@ -1761,8 +1771,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/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) }