Merge "Reapply "Add LocalNetworkConfig"" into main
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 0f35a4d..46308af 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -263,7 +263,12 @@
"name": "netd_updatable_unit_test[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
},
{
- "name": "ConnectivityCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
+ "name": "ConnectivityCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ }
+ ]
},
{
"name": "traffic_controller_unit_test[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 9132857..cd8eac8 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -96,6 +96,7 @@
},
binaries: [
"clatd",
+ "ethtool",
"netbpfload",
"ot-daemon",
],
diff --git a/common/flags.aconfig b/common/flags.aconfig
index cadc44f..2e552a1 100644
--- a/common/flags.aconfig
+++ b/common/flags.aconfig
@@ -13,3 +13,10 @@
description: "This flag controls the forbidden capability API"
bug: "302997505"
}
+
+flag {
+ name: "nsd_expired_services_removal"
+ namespace: "android_core_networking"
+ description: "Remove expired services from MdnsServiceCache"
+ bug: "304649384"
+}
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index b041260..cc3f019 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -1703,20 +1703,20 @@
am.addOnUidImportanceListener(new UidImportanceListener(handler),
mRunningAppActiveImportanceCutoff);
+ final MdnsFeatureFlags flags = new MdnsFeatureFlags.Builder()
+ .setIsMdnsOffloadFeatureEnabled(mDeps.isTetheringFeatureNotChickenedOut(
+ mContext, MdnsFeatureFlags.NSD_FORCE_DISABLE_MDNS_OFFLOAD))
+ .setIncludeInetAddressRecordsInProbing(mDeps.isFeatureEnabled(
+ mContext, MdnsFeatureFlags.INCLUDE_INET_ADDRESS_RECORDS_IN_PROBING))
+ .setIsExpiredServicesRemovalEnabled(mDeps.isTrunkStableFeatureEnabled(
+ MdnsFeatureFlags.NSD_EXPIRED_SERVICES_REMOVAL))
+ .build();
mMdnsSocketClient =
new MdnsMultinetworkSocketClient(handler.getLooper(), mMdnsSocketProvider,
LOGGER.forSubComponent("MdnsMultinetworkSocketClient"));
mMdnsDiscoveryManager = deps.makeMdnsDiscoveryManager(new ExecutorProvider(),
- mMdnsSocketClient, LOGGER.forSubComponent("MdnsDiscoveryManager"));
+ mMdnsSocketClient, LOGGER.forSubComponent("MdnsDiscoveryManager"), flags);
handler.post(() -> mMdnsSocketClient.setCallback(mMdnsDiscoveryManager));
- MdnsFeatureFlags flags = new MdnsFeatureFlags.Builder()
- .setIsMdnsOffloadFeatureEnabled(
- mDeps.isTetheringFeatureNotChickenedOut(
- mContext, MdnsFeatureFlags.NSD_FORCE_DISABLE_MDNS_OFFLOAD))
- .setIncludeInetAddressRecordsInProbing(
- mDeps.isFeatureEnabled(
- mContext, MdnsFeatureFlags.INCLUDE_INET_ADDRESS_RECORDS_IN_PROBING))
- .build();
mAdvertiser = deps.makeMdnsAdvertiser(handler.getLooper(), mMdnsSocketProvider,
new AdvertiserCallback(), LOGGER.forSubComponent("MdnsAdvertiser"), flags);
mClock = deps.makeClock();
@@ -1774,12 +1774,21 @@
}
/**
+ * @see DeviceConfigUtils#isTrunkStableFeatureEnabled
+ */
+ public boolean isTrunkStableFeatureEnabled(String feature) {
+ return DeviceConfigUtils.isTrunkStableFeatureEnabled(feature);
+ }
+
+ /**
* @see MdnsDiscoveryManager
*/
public MdnsDiscoveryManager makeMdnsDiscoveryManager(
@NonNull ExecutorProvider executorProvider,
- @NonNull MdnsMultinetworkSocketClient socketClient, @NonNull SharedLog sharedLog) {
- return new MdnsDiscoveryManager(executorProvider, socketClient, sharedLog);
+ @NonNull MdnsMultinetworkSocketClient socketClient, @NonNull SharedLog sharedLog,
+ @NonNull MdnsFeatureFlags featureFlags) {
+ return new MdnsDiscoveryManager(
+ executorProvider, socketClient, sharedLog, featureFlags);
}
/**
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
index 24e9fa8..766f999 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
@@ -53,6 +53,7 @@
@NonNull private final Handler handler;
@Nullable private final HandlerThread handlerThread;
@NonNull private final MdnsServiceCache serviceCache;
+ @NonNull private final MdnsFeatureFlags mdnsFeatureFlags;
private static class PerSocketServiceTypeClients {
private final ArrayMap<Pair<String, SocketKey>, MdnsServiceTypeClient> clients =
@@ -117,20 +118,22 @@
}
public MdnsDiscoveryManager(@NonNull ExecutorProvider executorProvider,
- @NonNull MdnsSocketClientBase socketClient, @NonNull SharedLog sharedLog) {
+ @NonNull MdnsSocketClientBase socketClient, @NonNull SharedLog sharedLog,
+ @NonNull MdnsFeatureFlags mdnsFeatureFlags) {
this.executorProvider = executorProvider;
this.socketClient = socketClient;
this.sharedLog = sharedLog;
this.perSocketServiceTypeClients = new PerSocketServiceTypeClients();
+ this.mdnsFeatureFlags = mdnsFeatureFlags;
if (socketClient.getLooper() != null) {
this.handlerThread = null;
this.handler = new Handler(socketClient.getLooper());
- this.serviceCache = new MdnsServiceCache(socketClient.getLooper());
+ this.serviceCache = new MdnsServiceCache(socketClient.getLooper(), mdnsFeatureFlags);
} else {
this.handlerThread = new HandlerThread(MdnsDiscoveryManager.class.getSimpleName());
this.handlerThread.start();
this.handler = new Handler(handlerThread.getLooper());
- this.serviceCache = new MdnsServiceCache(handlerThread.getLooper());
+ this.serviceCache = new MdnsServiceCache(handlerThread.getLooper(), mdnsFeatureFlags);
}
}
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsFeatureFlags.java b/service-t/src/com/android/server/connectivity/mdns/MdnsFeatureFlags.java
index a6f7871..6f7645e 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsFeatureFlags.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsFeatureFlags.java
@@ -20,16 +20,21 @@
*/
public class MdnsFeatureFlags {
/**
- * The feature flag for control whether the mDNS offload is enabled or not.
+ * A feature flag to control whether the mDNS offload is enabled or not.
*/
public static final String NSD_FORCE_DISABLE_MDNS_OFFLOAD = "nsd_force_disable_mdns_offload";
/**
- * The feature flag for controlling whether the probing question should include
+ * A feature flag to control whether the probing question should include
* InetAddressRecords or not.
*/
public static final String INCLUDE_INET_ADDRESS_RECORDS_IN_PROBING =
"include_inet_address_records_in_probing";
+ /**
+ * A feature flag to control whether expired services removal should be enabled.
+ */
+ public static final String NSD_EXPIRED_SERVICES_REMOVAL =
+ "nsd_expired_services_removal";
// Flag for offload feature
public final boolean mIsMdnsOffloadFeatureEnabled;
@@ -37,13 +42,17 @@
// Flag for including InetAddressRecords in probing questions.
public final boolean mIncludeInetAddressRecordsInProbing;
+ // Flag for expired services removal
+ public final boolean mIsExpiredServicesRemovalEnabled;
+
/**
* The constructor for {@link MdnsFeatureFlags}.
*/
public MdnsFeatureFlags(boolean isOffloadFeatureEnabled,
- boolean includeInetAddressRecordsInProbing) {
+ boolean includeInetAddressRecordsInProbing, boolean isExpiredServicesRemovalEnabled) {
mIsMdnsOffloadFeatureEnabled = isOffloadFeatureEnabled;
mIncludeInetAddressRecordsInProbing = includeInetAddressRecordsInProbing;
+ mIsExpiredServicesRemovalEnabled = isExpiredServicesRemovalEnabled;
}
@@ -57,6 +66,7 @@
private boolean mIsMdnsOffloadFeatureEnabled;
private boolean mIncludeInetAddressRecordsInProbing;
+ private boolean mIsExpiredServicesRemovalEnabled;
/**
* The constructor for {@link Builder}.
@@ -64,10 +74,13 @@
public Builder() {
mIsMdnsOffloadFeatureEnabled = false;
mIncludeInetAddressRecordsInProbing = false;
+ mIsExpiredServicesRemovalEnabled = true; // Default enabled.
}
/**
- * Set if the mDNS offload feature is enabled.
+ * Set whether the mDNS offload feature is enabled.
+ *
+ * @see #NSD_FORCE_DISABLE_MDNS_OFFLOAD
*/
public Builder setIsMdnsOffloadFeatureEnabled(boolean isMdnsOffloadFeatureEnabled) {
mIsMdnsOffloadFeatureEnabled = isMdnsOffloadFeatureEnabled;
@@ -75,7 +88,9 @@
}
/**
- * Set if the probing question should include InetAddressRecords.
+ * Set whether the probing question should include InetAddressRecords.
+ *
+ * @see #INCLUDE_INET_ADDRESS_RECORDS_IN_PROBING
*/
public Builder setIncludeInetAddressRecordsInProbing(
boolean includeInetAddressRecordsInProbing) {
@@ -84,12 +99,21 @@
}
/**
+ * Set whether the expired services removal is enabled.
+ *
+ * @see #NSD_EXPIRED_SERVICES_REMOVAL
+ */
+ public Builder setIsExpiredServicesRemovalEnabled(boolean isExpiredServicesRemovalEnabled) {
+ mIsExpiredServicesRemovalEnabled = isExpiredServicesRemovalEnabled;
+ return this;
+ }
+
+ /**
* Builds a {@link MdnsFeatureFlags} with the arguments supplied to this builder.
*/
public MdnsFeatureFlags build() {
- return new MdnsFeatureFlags(
- mIsMdnsOffloadFeatureEnabled, mIncludeInetAddressRecordsInProbing);
+ return new MdnsFeatureFlags(mIsMdnsOffloadFeatureEnabled,
+ mIncludeInetAddressRecordsInProbing, mIsExpiredServicesRemovalEnabled);
}
-
}
}
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
index f9ee0df..d3493c7 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
@@ -80,9 +80,12 @@
private final ArrayMap<CacheKey, ServiceExpiredCallback> mCallbacks = new ArrayMap<>();
@NonNull
private final Handler mHandler;
+ @NonNull
+ private final MdnsFeatureFlags mMdnsFeatureFlags;
- public MdnsServiceCache(@NonNull Looper looper) {
+ public MdnsServiceCache(@NonNull Looper looper, @NonNull MdnsFeatureFlags mdnsFeatureFlags) {
mHandler = new Handler(looper);
+ mMdnsFeatureFlags = mdnsFeatureFlags;
}
/**
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
index 25e59d5..cc67550 100644
--- a/service-t/src/com/android/server/net/NetworkStatsService.java
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -517,11 +517,12 @@
break;
}
case MSG_NOTIFY_NETWORK_STATUS: {
- // If no cached states, ignore.
- if (mLastNetworkStateSnapshots == null) break;
- // TODO (b/181642673): Protect mDefaultNetworks from concurrent accessing.
- handleNotifyNetworkStatus(
- mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface);
+ synchronized (mStatsLock) {
+ // If no cached states, ignore.
+ if (mLastNetworkStateSnapshots == null) break;
+ handleNotifyNetworkStatus(
+ mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface);
+ }
break;
}
case MSG_PERFORM_POLL_REGISTER_ALERT: {
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 6ce6fcf..2797b47 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -100,6 +100,11 @@
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_EGRESS;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_INGRESS;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_CREATE;
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;
@@ -280,6 +285,7 @@
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
import com.android.net.module.util.BinderUtils;
import com.android.net.module.util.BitUtils;
+import com.android.net.module.util.BpfUtils;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.InterfaceParams;
@@ -1529,6 +1535,14 @@
}
/**
+ * Get BPF program Id from CGROUP. See {@link BpfUtils#getProgramId}.
+ */
+ public int getBpfProgramId(final int attachType, @NonNull final String cgroupPath)
+ throws IOException {
+ return BpfUtils.getProgramId(attachType, cgroupPath);
+ }
+
+ /**
* Wraps {@link BroadcastOptionsShimImpl#newInstance(BroadcastOptions)}
*/
// TODO: when available in all active branches:
@@ -3252,6 +3266,26 @@
pw.decreaseIndent();
}
+ private void dumpBpfProgramStatus(IndentingPrintWriter pw) {
+ pw.println("Bpf Program Status:");
+ pw.increaseIndent();
+ try {
+ pw.print("CGROUP_INET_INGRESS: ");
+ pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_INGRESS, BpfUtils.CGROUP_PATH));
+ pw.print("CGROUP_INET_EGRESS: ");
+ pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_EGRESS, BpfUtils.CGROUP_PATH));
+ pw.print("CGROUP_INET_SOCK_CREATE: ");
+ pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_CREATE, BpfUtils.CGROUP_PATH));
+ pw.print("CGROUP_INET4_BIND: ");
+ pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_BIND, BpfUtils.CGROUP_PATH));
+ pw.print("CGROUP_INET6_BIND: ");
+ pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_BIND, BpfUtils.CGROUP_PATH));
+ } catch (IOException e) {
+ pw.println(" IOException");
+ }
+ pw.decreaseIndent();
+ }
+
@VisibleForTesting
static final String KEY_DESTROY_FROZEN_SOCKETS_VERSION = "destroy_frozen_sockets_version";
@VisibleForTesting
@@ -3866,6 +3900,9 @@
dumpCloseFrozenAppSockets(pw);
pw.println();
+ dumpBpfProgramStatus(pw);
+
+ pw.println();
if (!CollectionUtils.contains(args, SHORT_ARG)) {
pw.println();
@@ -10801,6 +10838,17 @@
Log.d(TAG, "Reevaluating network " + nai.network);
reportNetworkConnectivity(nai.network, !nai.isValidated());
return 0;
+ case "bpf-get-cgroup-program-id": {
+ // Usage : adb shell cmd connectivity bpf-get-cgroup-program-id <type>
+ // Get cgroup bpf program Id for the given type. See BpfUtils#getProgramId
+ // for more detail.
+ // If type can't be parsed, this throws NumberFormatException, which
+ // is passed back to adb who prints it.
+ final int type = Integer.parseInt(getNextArg());
+ final int ret = BpfUtils.getProgramId(type, BpfUtils.CGROUP_PATH);
+ pw.println(ret);
+ return 0;
+ }
default:
return handleDefaultCommands(cmd);
}
diff --git a/service/src/com/android/server/connectivity/ConnectivityNativeService.java b/service/src/com/android/server/connectivity/ConnectivityNativeService.java
index e16117b..cf6127f 100644
--- a/service/src/com/android/server/connectivity/ConnectivityNativeService.java
+++ b/service/src/com/android/server/connectivity/ConnectivityNativeService.java
@@ -16,9 +16,6 @@
package com.android.server.connectivity;
-import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND;
-import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -31,11 +28,9 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.BpfBitmap;
-import com.android.net.module.util.BpfUtils;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.PermissionUtils;
-import java.io.IOException;
import java.util.ArrayList;
/**
@@ -45,7 +40,7 @@
public static final String SERVICE_NAME = "connectivity_native";
private static final String TAG = ConnectivityNativeService.class.getSimpleName();
- private static final String CGROUP_PATH = "/sys/fs/cgroup";
+
private static final String BLOCKED_PORTS_MAP_PATH =
"/sys/fs/bpf/net_shared/map_block_blocked_ports_map";
diff --git a/staticlibs/device/com/android/net/module/util/BpfUtils.java b/staticlibs/device/com/android/net/module/util/BpfUtils.java
index f1546c0..6116a5f 100644
--- a/staticlibs/device/com/android/net/module/util/BpfUtils.java
+++ b/staticlibs/device/com/android/net/module/util/BpfUtils.java
@@ -32,9 +32,13 @@
// Defined in include/uapi/linux/bpf.h. Only adding the CGROUPS currently being used for now.
public static final int BPF_CGROUP_INET_INGRESS = 0;
public static final int BPF_CGROUP_INET_EGRESS = 1;
+ public static final int BPF_CGROUP_INET_SOCK_CREATE = 2;
public static final int BPF_CGROUP_INET4_BIND = 8;
public static final int BPF_CGROUP_INET6_BIND = 9;
+ // Note: This is only guaranteed to be accurate on U+ devices. It is likely to be accurate
+ // on T+ devices as well, but this is not guaranteed.
+ public static final String CGROUP_PATH = "/sys/fs/cgroup/";
/**
* Attach BPF program to CGROUP
@@ -53,6 +57,20 @@
}
/**
+ * Get BPF program Id from CGROUP.
+ *
+ * Note: This requires a 4.19 kernel which is only guaranteed on V+.
+ *
+ * @param attachType Bpf attach type. See bpf_attach_type in include/uapi/linux/bpf.h.
+ * @param cgroupPath Path of cgroup.
+ * @return Positive integer for a Program Id. 0 if no program is attached.
+ * @throws IOException if failed to open the cgroup directory or query bpf program.
+ */
+ public static int getProgramId(int attachType, @NonNull String cgroupPath) throws IOException {
+ return native_getProgramIdFromCgroup(attachType, cgroupPath);
+ }
+
+ /**
* Detach single BPF program from CGROUP
*/
public static void detachSingleProgram(int type, @NonNull String programPath,
diff --git a/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java b/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java
index 176b7bc..e9c39e4 100644
--- a/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java
+++ b/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java
@@ -108,6 +108,13 @@
}
/**
+ * Check whether or not IA Prefix option has 0 preferred and valid lifetimes.
+ */
+ public boolean withZeroLifetimes() {
+ return preferred == 0 && valid == 0;
+ }
+
+ /**
* Build an IA_PD prefix option with given specific parameters.
*/
public static ByteBuffer build(final short length, final long preferred, final long valid,
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index b69d7fb..42b0d59 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -2276,6 +2276,11 @@
}
@Override
+ public int getBpfProgramId(final int attachType, @NonNull final String cgroupPath) {
+ return 0;
+ }
+
+ @Override
public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) {
reset(mBroadcastOptionsShim);
return mBroadcastOptionsShim;
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 71bd330..771edb2 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -35,14 +35,17 @@
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;
@@ -220,7 +223,7 @@
anyInt(), anyString(), anyString(), anyString(), anyInt());
doReturn(false).when(mDeps).isMdnsDiscoveryManagerEnabled(any(Context.class));
doReturn(mDiscoveryManager).when(mDeps)
- .makeMdnsDiscoveryManager(any(), any(), any());
+ .makeMdnsDiscoveryManager(any(), any(), any(), any());
doReturn(mMulticastLock).when(mWifiManager).createMulticastLock(any());
doReturn(mSocketProvider).when(mDeps).makeMdnsSocketProvider(any(), any(), any(), any());
doReturn(DEFAULT_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF).when(mDeps).getDeviceConfigInt(
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsDiscoveryManagerTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsDiscoveryManagerTests.java
index e869b91..331a5b6 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsDiscoveryManagerTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsDiscoveryManagerTests.java
@@ -106,7 +106,7 @@
doReturn(thread.getLooper()).when(socketClient).getLooper();
doReturn(true).when(socketClient).supportsRequestingSpecificNetworks();
discoveryManager = new MdnsDiscoveryManager(executorProvider, socketClient,
- sharedLog) {
+ sharedLog, MdnsFeatureFlags.newBuilder().build()) {
@Override
MdnsServiceTypeClient createServiceTypeClient(@NonNull String serviceType,
@NonNull SocketKey socketKey) {
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt
index 1b6f120..2b3b834 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceCacheTest.kt
@@ -50,9 +50,6 @@
private val handler by lazy {
Handler(thread.looper)
}
- private val serviceCache by lazy {
- MdnsServiceCache(thread.looper)
- }
@Before
fun setUp() {
@@ -64,6 +61,11 @@
thread.quitSafely()
}
+ private fun makeFlags(isExpiredServicesRemovalEnabled: Boolean = false) =
+ MdnsFeatureFlags.Builder()
+ .setIsExpiredServicesRemovalEnabled(isExpiredServicesRemovalEnabled)
+ .build()
+
private fun <T> runningOnHandlerAndReturn(functor: (() -> T)): T {
val future = CompletableFuture<T>()
handler.post {
@@ -72,36 +74,51 @@
return future.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
}
- private fun addOrUpdateService(cacheKey: CacheKey, service: MdnsResponse): Unit =
- runningOnHandlerAndReturn { serviceCache.addOrUpdateService(cacheKey, service) }
+ private fun addOrUpdateService(
+ serviceCache: MdnsServiceCache,
+ cacheKey: CacheKey,
+ service: MdnsResponse
+ ): Unit = runningOnHandlerAndReturn { serviceCache.addOrUpdateService(cacheKey, service) }
- private fun removeService(serviceName: String, cacheKey: CacheKey): Unit =
- runningOnHandlerAndReturn { serviceCache.removeService(serviceName, cacheKey) }
+ private fun removeService(
+ serviceCache: MdnsServiceCache,
+ serviceName: String,
+ cacheKey: CacheKey
+ ): Unit = runningOnHandlerAndReturn { serviceCache.removeService(serviceName, cacheKey) }
- private fun getService(serviceName: String, cacheKey: CacheKey): MdnsResponse? =
- runningOnHandlerAndReturn { serviceCache.getCachedService(serviceName, cacheKey) }
+ private fun getService(
+ serviceCache: MdnsServiceCache,
+ serviceName: String,
+ cacheKey: CacheKey,
+ ): MdnsResponse? = runningOnHandlerAndReturn {
+ serviceCache.getCachedService(serviceName, cacheKey)
+ }
- private fun getServices(cacheKey: CacheKey): List<MdnsResponse> =
- runningOnHandlerAndReturn { serviceCache.getCachedServices(cacheKey) }
+ private fun getServices(
+ serviceCache: MdnsServiceCache,
+ cacheKey: CacheKey,
+ ): List<MdnsResponse> = runningOnHandlerAndReturn { serviceCache.getCachedServices(cacheKey) }
@Test
fun testAddAndRemoveService() {
- addOrUpdateService(cacheKey1, createResponse(SERVICE_NAME_1, SERVICE_TYPE_1))
- var response = getService(SERVICE_NAME_1, cacheKey1)
+ val serviceCache = MdnsServiceCache(thread.looper, makeFlags())
+ addOrUpdateService(serviceCache, cacheKey1, createResponse(SERVICE_NAME_1, SERVICE_TYPE_1))
+ var response = getService(serviceCache, SERVICE_NAME_1, cacheKey1)
assertNotNull(response)
assertEquals(SERVICE_NAME_1, response.serviceInstanceName)
- removeService(SERVICE_NAME_1, cacheKey1)
- response = getService(SERVICE_NAME_1, cacheKey1)
+ removeService(serviceCache, SERVICE_NAME_1, cacheKey1)
+ response = getService(serviceCache, SERVICE_NAME_1, cacheKey1)
assertNull(response)
}
@Test
fun testGetCachedServices_multipleServiceTypes() {
- addOrUpdateService(cacheKey1, createResponse(SERVICE_NAME_1, SERVICE_TYPE_1))
- addOrUpdateService(cacheKey1, createResponse(SERVICE_NAME_2, SERVICE_TYPE_1))
- addOrUpdateService(cacheKey2, createResponse(SERVICE_NAME_2, SERVICE_TYPE_2))
+ val serviceCache = MdnsServiceCache(thread.looper, makeFlags())
+ addOrUpdateService(serviceCache, cacheKey1, createResponse(SERVICE_NAME_1, SERVICE_TYPE_1))
+ addOrUpdateService(serviceCache, cacheKey1, createResponse(SERVICE_NAME_2, SERVICE_TYPE_1))
+ addOrUpdateService(serviceCache, cacheKey2, createResponse(SERVICE_NAME_2, SERVICE_TYPE_2))
- val responses1 = getServices(cacheKey1)
+ val responses1 = getServices(serviceCache, cacheKey1)
assertEquals(2, responses1.size)
assertTrue(responses1.stream().anyMatch { response ->
response.serviceInstanceName == SERVICE_NAME_1
@@ -109,19 +126,19 @@
assertTrue(responses1.any { response ->
response.serviceInstanceName == SERVICE_NAME_2
})
- val responses2 = getServices(cacheKey2)
+ val responses2 = getServices(serviceCache, cacheKey2)
assertEquals(1, responses2.size)
assertTrue(responses2.any { response ->
response.serviceInstanceName == SERVICE_NAME_2
})
- removeService(SERVICE_NAME_2, cacheKey1)
- val responses3 = getServices(cacheKey1)
+ removeService(serviceCache, SERVICE_NAME_2, cacheKey1)
+ val responses3 = getServices(serviceCache, cacheKey1)
assertEquals(1, responses3.size)
assertTrue(responses3.any { response ->
response.serviceInstanceName == SERVICE_NAME_1
})
- val responses4 = getServices(cacheKey2)
+ val responses4 = getServices(serviceCache, cacheKey2)
assertEquals(1, responses4.size)
assertTrue(responses4.any { response ->
response.serviceInstanceName == SERVICE_NAME_2
@@ -129,6 +146,6 @@
}
private fun createResponse(serviceInstanceName: String, serviceType: String) = MdnsResponse(
- 0 /* now */, "$serviceInstanceName.$serviceType".split(".").toTypedArray(),
+ 0 /* now */, "$serviceInstanceName.$serviceType".split(".").toTypedArray(),
socketKey.interfaceIndex, socketKey.network)
}
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
index fde5abd..ce154dd 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -193,7 +193,8 @@
thread = new HandlerThread("MdnsServiceTypeClientTests");
thread.start();
handler = new Handler(thread.getLooper());
- serviceCache = new MdnsServiceCache(thread.getLooper());
+ serviceCache = new MdnsServiceCache(
+ thread.getLooper(), MdnsFeatureFlags.newBuilder().build());
doAnswer(inv -> {
latestDelayMs = 0;