Merge "Only send resolve callbacks for subscribed service"
This commit is contained in:
@@ -174,6 +174,7 @@ public class MdnsServiceTypeClient {
|
||||
this.searchOptions = searchOptions;
|
||||
if (listeners.put(listener, searchOptions) == null) {
|
||||
for (MdnsResponse existingResponse : instanceNameToResponse.values()) {
|
||||
if (!responseMatchesOptions(existingResponse, searchOptions)) continue;
|
||||
final MdnsServiceInfo info =
|
||||
buildMdnsServiceInfoFromResponse(existingResponse, serviceTypeLabels);
|
||||
listener.onServiceNameDiscovered(info);
|
||||
@@ -199,6 +200,13 @@ public class MdnsServiceTypeClient {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean responseMatchesOptions(@NonNull MdnsResponse response,
|
||||
@NonNull MdnsSearchOptions options) {
|
||||
if (options.getResolveInstanceName() == null) return true;
|
||||
// DNS is case-insensitive, so ignore case in the comparison
|
||||
return options.getResolveInstanceName().equalsIgnoreCase(response.getServiceInstanceName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters {@code listener} from receiving discovery event of mDNS service instances.
|
||||
*
|
||||
@@ -274,6 +282,7 @@ public class MdnsServiceTypeClient {
|
||||
buildMdnsServiceInfoFromResponse(response, serviceTypeLabels);
|
||||
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
if (!responseMatchesOptions(response, listeners.valueAt(i))) continue;
|
||||
final MdnsServiceBrowserListener listener = listeners.keyAt(i);
|
||||
if (newServiceFound) {
|
||||
listener.onServiceNameDiscovered(serviceInfo);
|
||||
@@ -295,6 +304,7 @@ public class MdnsServiceTypeClient {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
if (!responseMatchesOptions(response, listeners.valueAt(i))) continue;
|
||||
final MdnsServiceBrowserListener listener = listeners.keyAt(i);
|
||||
final MdnsServiceInfo serviceInfo =
|
||||
buildMdnsServiceInfoFromResponse(response, serviceTypeLabels);
|
||||
@@ -512,6 +522,10 @@ public class MdnsServiceTypeClient {
|
||||
== 0) {
|
||||
iter.remove();
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
if (!responseMatchesOptions(existingResponse,
|
||||
listeners.valueAt(i))) {
|
||||
continue;
|
||||
}
|
||||
final MdnsServiceBrowserListener listener = listeners.keyAt(i);
|
||||
String serviceInstanceName =
|
||||
existingResponse.getServiceInstanceName();
|
||||
|
||||
@@ -992,6 +992,71 @@ public class MdnsServiceTypeClientTests {
|
||||
mockNetwork);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessResponse_ResolveExcludesOtherServices() {
|
||||
client = new MdnsServiceTypeClient(
|
||||
SERVICE_TYPE, mockSocketClient, currentThreadExecutor, mockNetwork);
|
||||
|
||||
final String requestedInstance = "instance1";
|
||||
final String otherInstance = "instance2";
|
||||
final String ipV4Address = "192.0.2.0";
|
||||
final String ipV6Address = "2001:db8::";
|
||||
|
||||
final MdnsSearchOptions resolveOptions = MdnsSearchOptions.newBuilder()
|
||||
// Use different case in the options
|
||||
.setResolveInstanceName("Instance1").build();
|
||||
|
||||
client.startSendAndReceive(mockListenerOne, resolveOptions);
|
||||
client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
|
||||
|
||||
// Complete response from instanceName
|
||||
client.processResponse(createResponse(
|
||||
requestedInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
|
||||
Collections.emptyMap() /* textAttributes */, TEST_TTL),
|
||||
INTERFACE_INDEX, mockNetwork);
|
||||
|
||||
// Complete response from otherInstanceName
|
||||
client.processResponse(createResponse(
|
||||
otherInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
|
||||
Collections.emptyMap() /* textAttributes */, TEST_TTL),
|
||||
INTERFACE_INDEX, mockNetwork);
|
||||
|
||||
// Address update from otherInstanceName
|
||||
client.processResponse(createResponse(
|
||||
otherInstance, ipV6Address, 5353, SERVICE_TYPE_LABELS,
|
||||
Collections.emptyMap(), TEST_TTL), INTERFACE_INDEX, mockNetwork);
|
||||
|
||||
// Goodbye from otherInstanceName
|
||||
client.processResponse(createResponse(
|
||||
otherInstance, ipV6Address, 5353, SERVICE_TYPE_LABELS,
|
||||
Collections.emptyMap(), 0L /* ttl */), INTERFACE_INDEX, mockNetwork);
|
||||
|
||||
// mockListenerOne gets notified for the requested instance
|
||||
verify(mockListenerOne).onServiceNameDiscovered(matchServiceName(requestedInstance));
|
||||
verify(mockListenerOne).onServiceFound(matchServiceName(requestedInstance));
|
||||
|
||||
// ...but does not get any callback for the other instance
|
||||
verify(mockListenerOne, never()).onServiceFound(matchServiceName(otherInstance));
|
||||
verify(mockListenerOne, never()).onServiceNameDiscovered(matchServiceName(otherInstance));
|
||||
verify(mockListenerOne, never()).onServiceUpdated(matchServiceName(otherInstance));
|
||||
verify(mockListenerOne, never()).onServiceRemoved(matchServiceName(otherInstance));
|
||||
|
||||
// mockListenerTwo gets notified for both though
|
||||
final InOrder inOrder = inOrder(mockListenerTwo);
|
||||
inOrder.verify(mockListenerTwo).onServiceNameDiscovered(
|
||||
matchServiceName(requestedInstance));
|
||||
inOrder.verify(mockListenerTwo).onServiceFound(matchServiceName(requestedInstance));
|
||||
|
||||
inOrder.verify(mockListenerTwo).onServiceNameDiscovered(matchServiceName(otherInstance));
|
||||
inOrder.verify(mockListenerTwo).onServiceFound(matchServiceName(otherInstance));
|
||||
inOrder.verify(mockListenerTwo).onServiceUpdated(matchServiceName(otherInstance));
|
||||
inOrder.verify(mockListenerTwo).onServiceRemoved(matchServiceName(otherInstance));
|
||||
}
|
||||
|
||||
private static MdnsServiceInfo matchServiceName(String name) {
|
||||
return argThat(info -> info.getServiceInstanceName().equals(name));
|
||||
}
|
||||
|
||||
// verifies that the right query was enqueued with the right delay, and send query by executing
|
||||
// the runnable.
|
||||
private void verifyAndSendQuery(int index, long timeInMs, boolean expectsUnicastResponse) {
|
||||
|
||||
Reference in New Issue
Block a user