Implement service found callback
Service found should be notified when receives the
onServiceNameDiscovered callbacks from
MdnsServiceBrowserListener.
Bug: 254166302
Test: atest FrameworksNetTests CtsNetTestCases
Change-Id: I3f41b4fe85cd85ad356fa764663187a88914412c
diff --git a/framework-t/src/android/net/nsd/NsdManager.java b/framework-t/src/android/net/nsd/NsdManager.java
index 668c34d..d340384 100644
--- a/framework-t/src/android/net/nsd/NsdManager.java
+++ b/framework-t/src/android/net/nsd/NsdManager.java
@@ -244,6 +244,8 @@
/** @hide */
public static final int MDNS_MONITORING_SOCKETS_CLEANUP = 23;
+ /** @hide */
+ public static final int MDNS_DISCOVERY_MANAGER_EVENT = 24;
/** Dns based service discovery protocol */
public static final int PROTOCOL_DNS_SD = 0x0001;
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index c93fcf6..0d3ffd1 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -17,6 +17,7 @@
package com.android.server;
import static android.net.ConnectivityManager.NETID_UNSET;
+import static android.net.nsd.NsdManager.MDNS_DISCOVERY_MANAGER_EVENT;
import static android.net.nsd.NsdManager.MDNS_SERVICE_EVENT;
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
@@ -182,7 +183,9 @@
@Override
public void onServiceNameDiscovered(@NonNull MdnsServiceInfo serviceInfo) {
- // TODO: implement service name discovered callback.
+ mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId,
+ NsdManager.SERVICE_FOUND,
+ new MdnsEvent(mClientId, mReqServiceInfo.getServiceType(), serviceInfo));
}
@Override
@@ -191,6 +194,24 @@
}
}
+ /**
+ * Data class of mdns service callback information.
+ */
+ private static class MdnsEvent {
+ final int mClientId;
+ @NonNull
+ final String mRequestedServiceType;
+ @NonNull
+ final MdnsServiceInfo mMdnsServiceInfo;
+
+ MdnsEvent(int clientId, @NonNull String requestedServiceType,
+ @NonNull MdnsServiceInfo mdnsServiceInfo) {
+ mClientId = clientId;
+ mRequestedServiceType = requestedServiceType;
+ mMdnsServiceInfo = mdnsServiceInfo;
+ }
+ }
+
private class NsdStateMachine extends StateMachine {
private final DefaultState mDefaultState = new DefaultState();
@@ -636,6 +657,11 @@
return NOT_HANDLED;
}
break;
+ case MDNS_DISCOVERY_MANAGER_EVENT:
+ if (!handleMdnsDiscoveryManagerEvent(msg.arg1, msg.arg2, msg.obj)) {
+ return NOT_HANDLED;
+ }
+ break;
default:
return NOT_HANDLED;
}
@@ -798,6 +824,45 @@
}
return true;
}
+
+ private NsdServiceInfo buildNsdServiceInfoFromMdnsEvent(final MdnsEvent event) {
+ final MdnsServiceInfo serviceInfo = event.mMdnsServiceInfo;
+ final String serviceType = event.mRequestedServiceType;
+ final String serviceName = serviceInfo.getServiceInstanceName();
+ final NsdServiceInfo servInfo = new NsdServiceInfo(serviceName, serviceType);
+ final Network network = serviceInfo.getNetwork();
+ setServiceNetworkForCallback(
+ servInfo,
+ network == null ? NETID_UNSET : network.netId,
+ serviceInfo.getInterfaceIndex());
+ return servInfo;
+ }
+
+ private boolean handleMdnsDiscoveryManagerEvent(
+ int transactionId, int code, Object obj) {
+ final ClientInfo clientInfo = mIdToClientInfoMap.get(transactionId);
+ if (clientInfo == null) {
+ Log.e(TAG, String.format(
+ "id %d for %d has no client mapping", transactionId, code));
+ return false;
+ }
+
+ final MdnsEvent event = (MdnsEvent) obj;
+ final int clientId = event.mClientId;
+ if (DBG) {
+ Log.d(TAG, String.format("MdnsDiscoveryManager event code=%s transactionId=%d",
+ NsdManager.nameOf(code), transactionId));
+ }
+ switch (code) {
+ case NsdManager.SERVICE_FOUND:
+ clientInfo.onServiceFound(
+ clientId, buildNsdServiceInfoFromMdnsEvent(event));
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
}
}
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 2fa1699..a42a7d7 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -73,6 +73,8 @@
import com.android.server.NsdService.Dependencies;
import com.android.server.connectivity.mdns.MdnsDiscoveryManager;
+import com.android.server.connectivity.mdns.MdnsServiceBrowserListener;
+import com.android.server.connectivity.mdns.MdnsServiceInfo;
import com.android.server.connectivity.mdns.MdnsSocketProvider;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
@@ -90,6 +92,7 @@
import org.mockito.MockitoAnnotations;
import java.util.LinkedList;
+import java.util.List;
import java.util.Queue;
// TODOs:
@@ -594,13 +597,35 @@
final Network network = new Network(999);
final String serviceTypeWithLocalDomain = SERVICE_TYPE + ".local";
// Verify the discovery start / stop.
+ final ArgumentCaptor<MdnsServiceBrowserListener> listenerCaptor =
+ ArgumentCaptor.forClass(MdnsServiceBrowserListener.class);
client.discoverServices(SERVICE_TYPE, PROTOCOL, network, r -> r.run(), discListener);
waitForIdle();
verify(mSocketProvider).startMonitoringSockets();
- verify(mDiscoveryManager).registerListener(eq(serviceTypeWithLocalDomain), any(),
- argThat(options -> network.equals(options.getNetwork())));
+ verify(mDiscoveryManager).registerListener(eq(serviceTypeWithLocalDomain),
+ listenerCaptor.capture(), argThat(options -> network.equals(options.getNetwork())));
verify(discListener, timeout(TIMEOUT_MS)).onDiscoveryStarted(SERVICE_TYPE);
+ final MdnsServiceBrowserListener listener = listenerCaptor.getValue();
+ final MdnsServiceInfo mdnsServiceInfo = new MdnsServiceInfo(
+ SERVICE_NAME, /* serviceInstanceName */
+ serviceTypeWithLocalDomain.split("\\."), /* serviceType */
+ List.of(), /* subtypes */
+ new String[] {"android", "local"}, /* hostName */
+ 12345, /* port */
+ "192.0.2.0", /* ipv4Address */
+ "2001:db8::", /* ipv6Address */
+ List.of(), /* textStrings */
+ List.of(), /* textEntries */
+ 1234, /* interfaceIndex */
+ network);
+ // Verify onServiceNameFound callback
+ listener.onServiceNameDiscovered(mdnsServiceInfo);
+ verify(discListener, timeout(TIMEOUT_MS)).onServiceFound(argThat(info ->
+ info.getServiceName().equals(SERVICE_NAME)
+ && info.getServiceType().equals(SERVICE_TYPE)
+ && info.getNetwork().equals(network)));
+
client.stopServiceDiscovery(discListener);
waitForIdle();
verify(mDiscoveryManager).unregisterListener(eq(serviceTypeWithLocalDomain), any());