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
This commit is contained in:
Paul Hu
2023-01-13 23:26:49 +08:00
parent 23fa202478
commit 019621e070
3 changed files with 95 additions and 3 deletions

View File

@@ -244,6 +244,8 @@ public final class NsdManager {
/** @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;

View File

@@ -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 @@ public class NsdService extends INsdManager.Stub {
@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 @@ public class NsdService extends INsdManager.Stub {
}
}
/**
* 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 @@ public class NsdService extends INsdManager.Stub {
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 @@ public class NsdService extends INsdManager.Stub {
}
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;
}
}
}

View File

@@ -73,6 +73,8 @@ import androidx.test.filters.SmallTest;
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.Mock;
import org.mockito.MockitoAnnotations;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
// TODOs:
@@ -594,13 +597,35 @@ public class NsdServiceTest {
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());