Merge "Add onServiceNameDiscovered/onServiceNameRemoved"

This commit is contained in:
Paul Hu
2022-12-07 02:00:33 +00:00
committed by Gerrit Code Review
3 changed files with 358 additions and 81 deletions

View File

@@ -18,6 +18,7 @@ package com.android.server.connectivity.mdns;
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -26,16 +27,18 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static java.nio.charset.StandardCharsets.UTF_8;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.InetAddresses;
import android.text.TextUtils;
import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
@@ -49,6 +52,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -72,7 +76,7 @@ import java.util.concurrent.TimeUnit;
@RunWith(DevSdkIgnoreRunner.class)
@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
public class MdnsServiceTypeClientTests {
private static final int INTERFACE_INDEX = 999;
private static final String SERVICE_TYPE = "_googlecast._tcp.local";
private static final String[] SERVICE_TYPE_LABELS = TextUtils.split(SERVICE_TYPE, "\\.");
@@ -379,15 +383,41 @@ public class MdnsServiceTypeClientTests {
assertNull(currentThreadExecutor.getAndClearLastScheduledRunnable());
}
private static void verifyServiceInfo(MdnsServiceInfo serviceInfo, String serviceName,
String[] serviceType, String ipv4Address, String ipv6Address, int port,
List<String> subTypes, Map<String, String> attributes, int interfaceIndex) {
assertEquals(serviceName, serviceInfo.getServiceInstanceName());
assertArrayEquals(serviceType, serviceInfo.getServiceType());
assertEquals(ipv4Address, serviceInfo.getIpv4Address());
assertEquals(ipv6Address, serviceInfo.getIpv6Address());
assertEquals(port, serviceInfo.getPort());
assertEquals(subTypes, serviceInfo.getSubtypes());
for (String key : attributes.keySet()) {
assertEquals(attributes.get(key), serviceInfo.getAttributeByKey(key));
}
assertEquals(interfaceIndex, serviceInfo.getInterfaceIndex());
}
@Test
public void processResponse_incompleteResponse() {
client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
MdnsResponse response = mock(MdnsResponse.class);
when(response.getServiceInstanceName()).thenReturn("service-instance-1");
doReturn(INTERFACE_INDEX).when(response).getInterfaceIndex();
when(response.isComplete()).thenReturn(false);
client.processResponse(response);
verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
null /* ipv4Address */,
null /* ipv6Address */,
0 /* port */,
List.of() /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
INTERFACE_INDEX);
verify(mockListenerOne, never()).onServiceFound(any(MdnsServiceInfo.class));
verify(mockListenerOne, never()).onServiceUpdated(any(MdnsServiceInfo.class));
@@ -404,7 +434,7 @@ public class MdnsServiceTypeClientTests {
"service-instance-1",
ipV4Address,
5353,
Collections.singletonList("ABCDE"),
/* subtype= */ "ABCDE",
Collections.emptyMap(),
/* interfaceIndex= */ 20);
client.processResponse(initialResponse);
@@ -415,14 +445,26 @@ public class MdnsServiceTypeClientTests {
"service-instance-1",
ipV4Address,
5354,
Collections.singletonList("ABCDE"),
/* subtype= */ "ABCDE",
Collections.singletonMap("key", "value"),
/* interfaceIndex= */ 20);
client.processResponse(secondResponse);
// Verify onServiceNameDiscovered was called once for the initial response.
verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
ipV4Address /* ipv4Address */,
null /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
20 /* interfaceIndex */);
// Verify onServiceFound was called once for the initial response.
verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(0);
MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(1);
assertEquals(initialServiceInfo.getServiceInstanceName(), "service-instance-1");
assertEquals(initialServiceInfo.getIpv4Address(), ipV4Address);
assertEquals(initialServiceInfo.getPort(), 5353);
@@ -432,7 +474,7 @@ public class MdnsServiceTypeClientTests {
// Verify onServiceUpdated was called once for the second response.
verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(1);
MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(2);
assertEquals(updatedServiceInfo.getServiceInstanceName(), "service-instance-1");
assertEquals(updatedServiceInfo.getIpv4Address(), ipV4Address);
assertEquals(updatedServiceInfo.getPort(), 5354);
@@ -453,7 +495,7 @@ public class MdnsServiceTypeClientTests {
"service-instance-1",
ipV6Address,
5353,
Collections.singletonList("ABCDE"),
/* subtype= */ "ABCDE",
Collections.emptyMap(),
/* interfaceIndex= */ 20);
client.processResponse(initialResponse);
@@ -464,7 +506,7 @@ public class MdnsServiceTypeClientTests {
"service-instance-1",
ipV6Address,
5354,
Collections.singletonList("ABCDE"),
/* subtype= */ "ABCDE",
Collections.singletonMap("key", "value"),
/* interfaceIndex= */ 20);
client.processResponse(secondResponse);
@@ -472,9 +514,21 @@ public class MdnsServiceTypeClientTests {
System.out.println("secondResponses ip"
+ secondResponse.getInet6AddressRecord().getInet6Address().getHostAddress());
// Verify onServiceNameDiscovered was called once for the initial response.
verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
null /* ipv4Address */,
ipV6Address /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
20 /* interfaceIndex */);
// Verify onServiceFound was called once for the initial response.
verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(0);
MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(1);
assertEquals(initialServiceInfo.getServiceInstanceName(), "service-instance-1");
assertEquals(initialServiceInfo.getIpv6Address(), ipV6Address);
assertEquals(initialServiceInfo.getPort(), 5353);
@@ -484,7 +538,7 @@ public class MdnsServiceTypeClientTests {
// Verify onServiceUpdated was called once for the second response.
verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(1);
MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(2);
assertEquals(updatedServiceInfo.getServiceInstanceName(), "service-instance-1");
assertEquals(updatedServiceInfo.getIpv6Address(), ipV6Address);
assertEquals(updatedServiceInfo.getPort(), 5354);
@@ -494,6 +548,23 @@ public class MdnsServiceTypeClientTests {
assertEquals(updatedServiceInfo.getInterfaceIndex(), 20);
}
private void verifyServiceRemovedNoCallback(MdnsServiceBrowserListener listener) {
verify(listener, never()).onServiceRemoved(any());
verify(listener, never()).onServiceNameRemoved(any());
}
private void verifyServiceRemovedCallback(MdnsServiceBrowserListener listener,
String serviceName, String[] serviceType, int interfaceIndex) {
verify(listener).onServiceRemoved(argThat(
info -> serviceName.equals(info.getServiceInstanceName())
&& Arrays.equals(serviceType, info.getServiceType())
&& info.getInterfaceIndex() == interfaceIndex));
verify(listener).onServiceNameRemoved(argThat(
info -> serviceName.equals(info.getServiceInstanceName())
&& Arrays.equals(serviceType, info.getServiceType())
&& info.getInterfaceIndex() == interfaceIndex));
}
@Test
public void processResponse_goodBye() throws Exception {
client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
@@ -501,37 +572,32 @@ public class MdnsServiceTypeClientTests {
final String serviceName = "service-instance-1";
final String ipV6Address = "2000:3333::da6c:63ff:fe7c:7483";
final int interfaceIndex = 999;
// Process the initial response.
final MdnsResponse initialResponse =
createResponse(
serviceName,
ipV6Address,
5353 /* port */,
Collections.singletonList("ABCDE"),
/* subtype= */ "ABCDE",
Collections.emptyMap(),
interfaceIndex);
INTERFACE_INDEX);
client.processResponse(initialResponse);
MdnsResponse response = mock(MdnsResponse.class);
doReturn("goodbye-service").when(response).getServiceInstanceName();
doReturn(interfaceIndex).when(response).getInterfaceIndex();
doReturn(INTERFACE_INDEX).when(response).getInterfaceIndex();
doReturn(true).when(response).isGoodbye();
client.processResponse(response);
// Verify onServiceRemoved won't be called if the service is not existed.
verify(mockListenerOne, never()).onServiceRemoved(any());
verify(mockListenerTwo, never()).onServiceRemoved(any());
// Verify removed callback won't be called if the service is not existed.
verifyServiceRemovedNoCallback(mockListenerOne);
verifyServiceRemovedNoCallback(mockListenerTwo);
// Verify onServiceRemoved would be called.
// Verify removed callback would be called.
doReturn(serviceName).when(response).getServiceInstanceName();
client.processResponse(response);
verify(mockListenerOne).onServiceRemoved(argThat(
info -> serviceName.equals(info.getServiceInstanceName())
&& Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
&& info.getInterfaceIndex() == interfaceIndex));
verify(mockListenerTwo).onServiceRemoved(argThat(
info -> serviceName.equals(info.getServiceInstanceName())
&& Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
&& info.getInterfaceIndex() == interfaceIndex));
verifyServiceRemovedCallback(
mockListenerOne, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
verifyServiceRemovedCallback(
mockListenerTwo, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
}
@Test
@@ -542,15 +608,28 @@ public class MdnsServiceTypeClientTests {
"service-instance-1",
"192.168.1.1",
5353,
Collections.singletonList("ABCDE"),
Collections.emptyMap());
/* subtype= */ "ABCDE",
Collections.emptyMap(),
INTERFACE_INDEX);
client.processResponse(initialResponse);
client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
// Verify onServiceNameDiscovered was called once for the existing response.
verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
"192.168.1.1" /* ipv4Address */,
null /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
INTERFACE_INDEX);
// Verify onServiceFound was called once for the existing response.
verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
MdnsServiceInfo existingServiceInfo = serviceInfoCaptor.getAllValues().get(0);
MdnsServiceInfo existingServiceInfo = serviceInfoCaptor.getAllValues().get(1);
assertEquals(existingServiceInfo.getServiceInstanceName(), "service-instance-1");
assertEquals(existingServiceInfo.getIpv4Address(), "192.168.1.1");
assertEquals(existingServiceInfo.getPort(), 5353);
@@ -567,6 +646,7 @@ public class MdnsServiceTypeClientTests {
// Verify onServiceFound was not called on the newly registered listener after the existing
// response is gone.
verify(mockListenerTwo, never()).onServiceNameDiscovered(any(MdnsServiceInfo.class));
verify(mockListenerTwo, never()).onServiceFound(any(MdnsServiceInfo.class));
}
@@ -580,9 +660,9 @@ public class MdnsServiceTypeClientTests {
// Process the initial response.
MdnsResponse initialResponse =
createResponse(
createMockResponse(
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
Map.of());
Map.of(), INTERFACE_INDEX);
client.processResponse(initialResponse);
// Clear the scheduled runnable.
@@ -592,8 +672,8 @@ public class MdnsServiceTypeClientTests {
when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
firstMdnsTask.run();
// Verify onServiceRemoved was not called.
verify(mockListenerOne, never()).onServiceRemoved(any());
// Verify removed callback was not called.
verifyServiceRemovedNoCallback(mockListenerOne);
}
@Test
@@ -614,9 +694,9 @@ public class MdnsServiceTypeClientTests {
// Process the initial response.
MdnsResponse initialResponse =
createResponse(
createMockResponse(
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
Map.of(), 999 /* interfaceIndex */);
Map.of(), INTERFACE_INDEX);
client.processResponse(initialResponse);
// Clear the scheduled runnable.
@@ -626,18 +706,16 @@ public class MdnsServiceTypeClientTests {
when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 1000);
firstMdnsTask.run();
// Verify onServiceRemoved was not called.
verify(mockListenerOne, never()).onServiceRemoved(any());
// Verify removed callback was not called.
verifyServiceRemovedNoCallback(mockListenerOne);
// Simulate the case where the response is after TTL.
when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
firstMdnsTask.run();
// Verify onServiceRemoved was called.
verify(mockListenerOne, times(1)).onServiceRemoved(argThat(
info -> serviceInstanceName.equals(info.getServiceInstanceName())
&& Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
&& info.getInterfaceIndex() == 999));
// Verify removed callback was called.
verifyServiceRemovedCallback(
mockListenerOne, serviceInstanceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
}
@Test
@@ -656,9 +734,9 @@ public class MdnsServiceTypeClientTests {
// Process the initial response.
MdnsResponse initialResponse =
createResponse(
createMockResponse(
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
Map.of());
Map.of(), INTERFACE_INDEX);
client.processResponse(initialResponse);
// Clear the scheduled runnable.
@@ -668,8 +746,8 @@ public class MdnsServiceTypeClientTests {
when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
firstMdnsTask.run();
// Verify onServiceRemoved was not called.
verify(mockListenerOne, never()).onServiceRemoved(any());
// Verify removed callback was not called.
verifyServiceRemovedNoCallback(mockListenerOne);
}
@Test
@@ -690,9 +768,9 @@ public class MdnsServiceTypeClientTests {
// Process the initial response.
MdnsResponse initialResponse =
createResponse(
createMockResponse(
serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
Map.of(), 999 /* interfaceIndex */);
Map.of(), INTERFACE_INDEX);
client.processResponse(initialResponse);
// Clear the scheduled runnable.
@@ -702,11 +780,117 @@ public class MdnsServiceTypeClientTests {
when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
firstMdnsTask.run();
// Verify onServiceRemoved was called.
verify(mockListenerOne, times(1)).onServiceRemoved(argThat(
info -> serviceInstanceName.equals(info.getServiceInstanceName())
&& Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
&& info.getInterfaceIndex() == 999));
// Verify removed callback was called.
verifyServiceRemovedCallback(
mockListenerOne, serviceInstanceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
}
@Test
public void testProcessResponse_InOrder() throws Exception {
final String serviceName = "service-instance";
final String ipV4Address = "192.0.2.0";
final String ipV6Address = "2001:db8::";
client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
InOrder inOrder = inOrder(mockListenerOne);
// Process the initial response which is incomplete.
final MdnsResponse initialResponse =
createResponse(
serviceName,
null,
5353,
"ABCDE" /* subtype */,
Collections.emptyMap(),
INTERFACE_INDEX);
client.processResponse(initialResponse);
// Process a second response which has ip address to make response become complete.
final MdnsResponse secondResponse =
createResponse(
serviceName,
ipV4Address,
5353,
"ABCDE" /* subtype */,
Collections.emptyMap(),
INTERFACE_INDEX);
client.processResponse(secondResponse);
// Process a third response with a different ip address, port and updated text attributes.
final MdnsResponse thirdResponse =
createResponse(
serviceName,
ipV6Address,
5354,
"ABCDE" /* subtype */,
Collections.singletonMap("key", "value"),
INTERFACE_INDEX);
client.processResponse(thirdResponse);
// Process the last response which is goodbye message.
final MdnsResponse lastResponse = mock(MdnsResponse.class);
doReturn(serviceName).when(lastResponse).getServiceInstanceName();
doReturn(true).when(lastResponse).isGoodbye();
client.processResponse(lastResponse);
// Verify onServiceNameDiscovered was first called for the initial response.
inOrder.verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
serviceName,
SERVICE_TYPE_LABELS,
null /* ipv4Address */,
null /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
INTERFACE_INDEX);
// Verify onServiceFound was second called for the second response.
inOrder.verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(1),
serviceName,
SERVICE_TYPE_LABELS,
ipV4Address /* ipv4Address */,
null /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
INTERFACE_INDEX);
// Verify onServiceUpdated was third called for the third response.
inOrder.verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(2),
serviceName,
SERVICE_TYPE_LABELS,
ipV4Address /* ipv4Address */,
ipV6Address /* ipv6Address */,
5354 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", "value") /* attributes */,
INTERFACE_INDEX);
// Verify onServiceRemoved was called for the last response.
inOrder.verify(mockListenerOne).onServiceRemoved(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(3),
serviceName,
SERVICE_TYPE_LABELS,
ipV4Address /* ipv4Address */,
ipV6Address /* ipv6Address */,
5354 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", "value") /* attributes */,
INTERFACE_INDEX);
// Verify onServiceNameRemoved was called for the last response.
inOrder.verify(mockListenerOne).onServiceNameRemoved(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(4),
serviceName,
SERVICE_TYPE_LABELS,
ipV4Address /* ipv4Address */,
ipV6Address /* ipv6Address */,
5354 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", "value") /* attributes */,
INTERFACE_INDEX);
}
// verifies that the right query was enqueued with the right delay, and send query by executing
@@ -771,19 +955,8 @@ public class MdnsServiceTypeClientTests {
}
}
private MdnsResponse createResponse(
@NonNull String serviceInstanceName,
@NonNull String host,
int port,
@NonNull List<String> subtypes,
@NonNull Map<String, String> textAttributes)
throws Exception {
return createResponse(serviceInstanceName, host, port, subtypes, textAttributes,
/* interfaceIndex= */ -1);
}
// Creates a complete mDNS response.
private MdnsResponse createResponse(
// Creates a mock mDNS response.
private MdnsResponse createMockResponse(
@NonNull String serviceInstanceName,
@NonNull String host,
int port,
@@ -830,4 +1003,73 @@ public class MdnsServiceTypeClientTests {
doReturn(new ArrayList<>(subtypes)).when(response).getSubtypes();
return response;
}
// Creates a mDNS response.
private MdnsResponse createResponse(
@NonNull String serviceInstanceName,
@Nullable String host,
int port,
@NonNull String subtype,
@NonNull Map<String, String> textAttributes,
int interfaceIndex)
throws Exception {
MdnsResponse response = new MdnsResponse(0);
response.setInterfaceIndex(interfaceIndex);
// Set PTR record
final MdnsPointerRecord pointerRecord = new MdnsPointerRecord(
new String[]{subtype, MdnsConstants.SUBTYPE_LABEL, "test"} /* name */,
0L /* receiptTimeMillis */,
false /* cacheFlush */,
120000L /* ttlMillis */,
new String[]{serviceInstanceName});
response.addPointerRecord(pointerRecord);
// Set SRV record.
final MdnsServiceRecord serviceRecord = new MdnsServiceRecord(
new String[] {"service"} /* name */,
0L /* receiptTimeMillis */,
false /* cacheFlush */,
120000L /* ttlMillis */,
0 /* servicePriority */,
0 /* serviceWeight */,
port,
new String[]{"hostname"});
response.setServiceRecord(serviceRecord);
// Set A/AAAA record.
if (host != null) {
if (InetAddresses.parseNumericAddress(host) instanceof Inet6Address) {
final MdnsInetAddressRecord inetAddressRecord = new MdnsInetAddressRecord(
new String[] {"address"} /* name */,
0L /* receiptTimeMillis */,
false /* cacheFlush */,
120000L /* ttlMillis */,
Inet6Address.getByName(host));
response.setInet6AddressRecord(inetAddressRecord);
} else {
final MdnsInetAddressRecord inetAddressRecord = new MdnsInetAddressRecord(
new String[] {"address"} /* name */,
0L /* receiptTimeMillis */,
false /* cacheFlush */,
120000L /* ttlMillis */,
Inet4Address.getByName(host));
response.setInet4AddressRecord(inetAddressRecord);
}
}
// Set TXT record.
final List<TextEntry> textEntries = new ArrayList<>();
for (Map.Entry<String, String> kv : textAttributes.entrySet()) {
textEntries.add(new TextEntry(kv.getKey(), kv.getValue().getBytes(UTF_8)));
}
final MdnsTextRecord textRecord = new MdnsTextRecord(
new String[] {"text"} /* name */,
0L /* receiptTimeMillis */,
false /* cacheFlush */,
120000L /* ttlMillis */,
textEntries);
response.setTextRecord(textRecord);
return response;
}
}