Merge "Revert "[mdns] support regsitering hosts in NsdPublisher"" into main
diff --git a/thread/service/java/com/android/server/thread/NsdPublisher.java b/thread/service/java/com/android/server/thread/NsdPublisher.java
index 440c2c3..c74c023 100644
--- a/thread/service/java/com/android/server/thread/NsdPublisher.java
+++ b/thread/service/java/com/android/server/thread/NsdPublisher.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.content.Context;
-import android.net.InetAddresses;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.os.Handler;
@@ -34,7 +33,6 @@
import com.android.server.thread.openthread.INsdPublisher;
import com.android.server.thread.openthread.INsdStatusReceiver;
-import java.net.InetAddress;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
@@ -121,30 +119,6 @@
return serviceInfo;
}
- @Override
- public void registerHost(
- String name, List<String> addresses, INsdStatusReceiver receiver, int listenerId) {
- postRegistrationJob(
- () -> {
- NsdServiceInfo serviceInfo = buildServiceInfoForHost(name, addresses);
- registerInternal(serviceInfo, receiver, listenerId, "host");
- });
- }
-
- private static NsdServiceInfo buildServiceInfoForHost(
- String name, List<String> addressStrings) {
- NsdServiceInfo serviceInfo = new NsdServiceInfo();
-
- serviceInfo.setHostname(name);
- ArrayList<InetAddress> addresses = new ArrayList<>(addressStrings.size());
- for (String addressString : addressStrings) {
- addresses.add(InetAddresses.parseNumericAddress(addressString));
- }
- serviceInfo.setHostAddresses(addresses);
-
- return serviceInfo;
- }
-
private void registerInternal(
NsdServiceInfo serviceInfo,
INsdStatusReceiver receiver,
diff --git a/thread/tests/integration/Android.bp b/thread/tests/integration/Android.bp
index 9677ec5..6ba192d 100644
--- a/thread/tests/integration/Android.bp
+++ b/thread/tests/integration/Android.bp
@@ -31,7 +31,6 @@
"net-utils-device-common",
"net-utils-device-common-bpf",
"testables",
- "ThreadNetworkTestUtils",
"truth",
],
libs: [
diff --git a/thread/tests/integration/src/android/net/thread/ServiceDiscoveryTest.java b/thread/tests/integration/src/android/net/thread/ServiceDiscoveryTest.java
deleted file mode 100644
index 9bc92c7..0000000
--- a/thread/tests/integration/src/android/net/thread/ServiceDiscoveryTest.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.thread;
-
-import static android.Manifest.permission.NETWORK_SETTINGS;
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.thread.ThreadNetworkManager.PERMISSION_THREAD_NETWORK_PRIVILEGED;
-import static android.net.thread.utils.IntegrationTestUtils.JOIN_TIMEOUT;
-import static android.net.thread.utils.IntegrationTestUtils.RESTART_JOIN_TIMEOUT;
-import static android.net.thread.utils.IntegrationTestUtils.SERVICE_DISCOVERY_TIMEOUT;
-import static android.net.thread.utils.IntegrationTestUtils.discoverForServiceLost;
-import static android.net.thread.utils.IntegrationTestUtils.discoverService;
-import static android.net.thread.utils.IntegrationTestUtils.isSimulatedThreadRadioSupported;
-import static android.net.thread.utils.IntegrationTestUtils.resolveService;
-import static android.net.thread.utils.IntegrationTestUtils.resolveServiceUntil;
-import static android.net.thread.utils.IntegrationTestUtils.waitFor;
-
-import static com.android.testutils.TestPermissionUtil.runAsShell;
-
-import static com.google.common.io.BaseEncoding.base16;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assume.assumeNotNull;
-import static org.junit.Assume.assumeTrue;
-
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-import android.content.Context;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.net.thread.utils.FullThreadDevice;
-import android.net.thread.utils.OtDaemonController;
-import android.net.thread.utils.TapTestNetworkTracker;
-import android.os.HandlerThread;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.common.truth.Correspondence;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet6Address;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeoutException;
-
-/** Integration test cases for Service Discovery feature. */
-@RunWith(AndroidJUnit4.class)
-@LargeTest
-public class ServiceDiscoveryTest {
- private static final String TAG = ServiceDiscoveryTest.class.getSimpleName();
- private static final int NUM_FTD = 3;
- private final Context mContext = ApplicationProvider.getApplicationContext();
-
- private HandlerThread mHandlerThread;
- private ThreadNetworkController mController;
- private NsdManager mNsdManager;
- private TapTestNetworkTracker mTestNetworkTracker;
- private List<FullThreadDevice> mFtds;
-
- // A valid Thread Active Operational Dataset generated from OpenThread CLI "dataset init new".
- private static final byte[] DEFAULT_DATASET_TLVS =
- base16().decode(
- "0E080000000000010000000300001335060004001FFFE002"
- + "08ACC214689BC40BDF0708FD64DB1225F47E0B0510F26B31"
- + "53760F519A63BAFDDFFC80D2AF030F4F70656E5468726561"
- + "642D643961300102D9A00410A245479C836D551B9CA557F7"
- + "B9D351B40C0402A0FFF8");
- private static final ActiveOperationalDataset DEFAULT_DATASET =
- ActiveOperationalDataset.fromThreadTlvs(DEFAULT_DATASET_TLVS);
-
- private static final Correspondence<byte[], byte[]> BYTE_ARRAY_EQUALITY =
- Correspondence.from(Arrays::equals, "is equivalent to");
-
- @Before
- public void setUp() throws Exception {
- final ThreadNetworkManager manager = mContext.getSystemService(ThreadNetworkManager.class);
- if (manager != null) {
- mController = manager.getAllThreadNetworkControllers().get(0);
- }
-
- // Run the tests on only devices where the Thread feature is available.
- assumeNotNull(mController);
-
- // Run the tests only when the device uses simulated Thread radio.
- assumeTrue(isSimulatedThreadRadioSupported());
-
- // BR forms a network.
- CompletableFuture<Void> joinFuture = new CompletableFuture<>();
- runAsShell(
- PERMISSION_THREAD_NETWORK_PRIVILEGED,
- () -> mController.join(DEFAULT_DATASET, directExecutor(), joinFuture::complete));
- joinFuture.get(RESTART_JOIN_TIMEOUT.toMillis(), MILLISECONDS);
-
- mNsdManager = mContext.getSystemService(NsdManager.class);
-
- mHandlerThread = new HandlerThread(TAG);
- mHandlerThread.start();
-
- mTestNetworkTracker = new TapTestNetworkTracker(mContext, mHandlerThread.getLooper());
- assertThat(mTestNetworkTracker).isNotNull();
- runAsShell(
- PERMISSION_THREAD_NETWORK_PRIVILEGED,
- NETWORK_SETTINGS,
- () -> {
- CompletableFuture<Void> future = new CompletableFuture<>();
- mController.setTestNetworkAsUpstream(
- mTestNetworkTracker.getInterfaceName(),
- directExecutor(),
- v -> future.complete(null));
- future.get(5, SECONDS);
- });
- // Create the FTDs in setUp() so that the FTDs can be safely released in tearDown().
- // Don't create new FTDs in test cases.
- mFtds = new ArrayList<>();
- for (int i = 0; i < NUM_FTD; ++i) {
- FullThreadDevice ftd = new FullThreadDevice(10 + i /* node ID */);
- ftd.autoStartSrpClient();
- mFtds.add(ftd);
- }
- }
-
- @After
- public void tearDown() throws Exception {
- if (mController == null) {
- return;
- }
- if (!isSimulatedThreadRadioSupported()) {
- return;
- }
- for (FullThreadDevice ftd : mFtds) {
- // Clear registered SRP hosts and services
- if (ftd.isSrpHostRegistered()) {
- ftd.removeSrpHost();
- }
- ftd.destroy();
- }
- if (mTestNetworkTracker != null) {
- mTestNetworkTracker.tearDown();
- }
- if (mHandlerThread != null) {
- mHandlerThread.quitSafely();
- mHandlerThread.join();
- }
- runAsShell(
- PERMISSION_THREAD_NETWORK_PRIVILEGED,
- NETWORK_SETTINGS,
- () -> {
- CompletableFuture<Void> setUpstreamFuture = new CompletableFuture<>();
- CompletableFuture<Void> leaveFuture = new CompletableFuture<>();
- mController.setTestNetworkAsUpstream(
- null, directExecutor(), v -> setUpstreamFuture.complete(null));
- mController.leave(directExecutor(), v -> leaveFuture.complete(null));
- setUpstreamFuture.get(5, SECONDS);
- leaveFuture.get(5, SECONDS);
- });
- }
-
- @Test
- public void advertisingProxy_multipleSrpClientsRegisterServices_servicesResolvableByMdns()
- throws Exception {
- /*
- * <pre>
- * Topology:
- * Thread
- * Border Router -------------- Full Thread device 1
- * (Cuttlefish) |
- * +------ Full Thread device 2
- * |
- * +------ Full Thread device 3
- * </pre>
- */
-
- // Creates Full Thread Devices (FTD) and let them join the network.
- for (FullThreadDevice ftd : mFtds) {
- ftd.joinNetwork(DEFAULT_DATASET);
- ftd.waitForStateAnyOf(List.of("router", "child"), JOIN_TIMEOUT);
- }
-
- int randomId = new Random().nextInt(10_000);
-
- String serviceNamePrefix = "service-" + randomId + "-";
- String serviceTypePrefix = "_test" + randomId;
- String hostnamePrefix = "host-" + randomId + "-";
-
- // For every FTD, let it register an SRP service.
- for (int i = 0; i < mFtds.size(); ++i) {
- FullThreadDevice ftd = mFtds.get(i);
- ftd.setSrpHostname(hostnamePrefix + i);
- ftd.setSrpHostAddresses(List.of(ftd.getOmrAddress(), ftd.getMlEid()));
- ftd.addSrpService(
- serviceNamePrefix + i,
- serviceTypePrefix + i + "._tcp",
- List.of("_sub1", "_sub2"),
- 12345 /* port */,
- Map.of("key1", bytes(0x01, 0x02), "key2", bytes(i)));
- }
-
- // Check the advertised services are discoverable and resolvable by NsdManager
- for (int i = 0; i < mFtds.size(); ++i) {
- NsdServiceInfo discoveredService =
- discoverService(mNsdManager, serviceTypePrefix + i + "._tcp");
- assertThat(discoveredService).isNotNull();
- NsdServiceInfo resolvedService = resolveService(mNsdManager, discoveredService);
- assertThat(resolvedService.getServiceName()).isEqualTo(serviceNamePrefix + i);
- assertThat(resolvedService.getServiceType()).isEqualTo(serviceTypePrefix + i + "._tcp");
- assertThat(resolvedService.getPort()).isEqualTo(12345);
- assertThat(resolvedService.getAttributes())
- .comparingValuesUsing(BYTE_ARRAY_EQUALITY)
- .containsExactly("key1", bytes(0x01, 0x02), "key2", bytes(i));
- assertThat(resolvedService.getHostname()).isEqualTo(hostnamePrefix + i);
- assertThat(resolvedService.getHostAddresses())
- .containsExactly(mFtds.get(i).getOmrAddress());
- }
- }
-
- @Test
- public void advertisingProxy_srpClientUpdatesService_updatedServiceResolvableByMdns()
- throws Exception {
- /*
- * <pre>
- * Topology:
- * Thread
- * Border Router -------------- Full Thread device
- * (Cuttlefish)
- * </pre>
- */
-
- // Creates a Full Thread Devices (FTD) and let it join the network.
- FullThreadDevice ftd = mFtds.get(0);
- ftd.joinNetwork(DEFAULT_DATASET);
- ftd.waitForStateAnyOf(List.of("router", "child"), JOIN_TIMEOUT);
- ftd.setSrpHostname("my-host");
- ftd.setSrpHostAddresses(List.of((Inet6Address) parseNumericAddress("2001:db8::1")));
- ftd.addSrpService(
- "my-service",
- "_test._tcp",
- Collections.emptyList() /* subtypes */,
- 12345 /* port */,
- Map.of("key1", bytes(0x01, 0x02), "key2", bytes(0x03)));
-
- // Update the host addresses
- ftd.setSrpHostAddresses(
- List.of(
- (Inet6Address) parseNumericAddress("2001:db8::1"),
- (Inet6Address) parseNumericAddress("2001:db8::2")));
- // Update the service
- ftd.updateSrpService(
- "my-service", "_test._tcp", List.of("_sub3"), 11111, Map.of("key1", bytes(0x04)));
- waitFor(ftd::isSrpHostRegistered, SERVICE_DISCOVERY_TIMEOUT);
-
- // Check the advertised service is discoverable and resolvable by NsdManager
- NsdServiceInfo discoveredService = discoverService(mNsdManager, "_test._tcp");
- assertThat(discoveredService).isNotNull();
- NsdServiceInfo resolvedService =
- resolveServiceUntil(
- mNsdManager,
- discoveredService,
- s -> s.getPort() == 11111 && s.getHostAddresses().size() == 2);
- assertThat(resolvedService.getServiceName()).isEqualTo("my-service");
- assertThat(resolvedService.getServiceType()).isEqualTo("_test._tcp");
- assertThat(resolvedService.getPort()).isEqualTo(11111);
- assertThat(resolvedService.getAttributes())
- .comparingValuesUsing(BYTE_ARRAY_EQUALITY)
- .containsExactly("key1", bytes(0x04));
- assertThat(resolvedService.getHostname()).isEqualTo("my-host");
- assertThat(resolvedService.getHostAddresses())
- .containsExactly(
- parseNumericAddress("2001:db8::1"), parseNumericAddress("2001:db8::2"));
- }
-
- @Test
- public void advertisingProxy_srpClientUnregistersService_serviceIsNotDiscoverableByMdns()
- throws Exception {
- /*
- * <pre>
- * Topology:
- * Thread
- * Border Router -------------- Full Thread device
- * (Cuttlefish)
- * </pre>
- */
-
- // Creates a Full Thread Devices (FTD) and let it join the network.
- FullThreadDevice ftd = mFtds.get(0);
- ftd.joinNetwork(DEFAULT_DATASET);
- ftd.waitForStateAnyOf(List.of("router", "child"), JOIN_TIMEOUT);
- ftd.setSrpHostname("my-host");
- ftd.setSrpHostAddresses(
- List.of(
- (Inet6Address) parseNumericAddress("2001:db8::1"),
- (Inet6Address) parseNumericAddress("2001:db8::2")));
- ftd.addSrpService(
- "my-service",
- "_test._udp",
- List.of("_sub1"),
- 12345 /* port */,
- Map.of("key1", bytes(0x01, 0x02), "key2", bytes(0x03)));
- // Wait for the service to be discoverable by NsdManager.
- assertThat(discoverService(mNsdManager, "_test._udp")).isNotNull();
-
- // Unregister the service.
- CompletableFuture<NsdServiceInfo> serviceLostFuture = new CompletableFuture<>();
- NsdManager.DiscoveryListener listener =
- discoverForServiceLost(mNsdManager, "_test._udp", serviceLostFuture);
- ftd.removeSrpService("my-service", "_test._udp", true /* notifyServer */);
-
- // Verify the service becomes lost.
- try {
- serviceLostFuture.get(SERVICE_DISCOVERY_TIMEOUT.toMillis(), MILLISECONDS);
- } finally {
- mNsdManager.stopServiceDiscovery(listener);
- }
- assertThrows(TimeoutException.class, () -> discoverService(mNsdManager, "_test._udp"));
- }
-
- private static byte[] bytes(int... byteInts) {
- byte[] bytes = new byte[byteInts.length];
- for (int i = 0; i < byteInts.length; ++i) {
- bytes[i] = (byte) byteInts[i];
- }
- return bytes;
- }
-}
diff --git a/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java b/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java
index 6306a65..6cb1675 100644
--- a/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java
+++ b/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java
@@ -15,7 +15,6 @@
*/
package android.net.thread.utils;
-import static android.net.thread.utils.IntegrationTestUtils.SERVICE_DISCOVERY_TIMEOUT;
import static android.net.thread.utils.IntegrationTestUtils.waitFor;
import static com.google.common.io.BaseEncoding.base16;
@@ -26,19 +25,15 @@
import android.net.IpPrefix;
import android.net.thread.ActiveOperationalDataset;
-import com.google.errorprone.annotations.FormatMethod;
-
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Inet6Address;
-import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -196,7 +191,7 @@
public void udpBind(Inet6Address address, int port) {
udpClose();
udpOpen();
- executeCommand("udp bind %s %d", address.getHostAddress(), port);
+ executeCommand(String.format("udp bind %s %d", address.getHostAddress(), port));
}
/** Returns the message received on the UDP socket. */
@@ -209,117 +204,6 @@
return matcher.group(4);
}
- /** Enables the SRP client and run in autostart mode. */
- public void autoStartSrpClient() {
- executeCommand("srp client autostart enable");
- }
-
- /** Sets the hostname (e.g. "MyHost") for the SRP client. */
- public void setSrpHostname(String hostname) {
- executeCommand("srp client host name " + hostname);
- }
-
- /** Sets the host addresses for the SRP client. */
- public void setSrpHostAddresses(List<Inet6Address> addresses) {
- executeCommand(
- "srp client host address "
- + String.join(
- " ",
- addresses.stream().map(Inet6Address::getHostAddress).toList()));
- }
-
- /** Removes the SRP host */
- public void removeSrpHost() {
- executeCommand("srp client host remove 1 1");
- }
-
- /**
- * Adds an SRP service for the SRP client and wait for the registration to complete.
- *
- * @param serviceName the service name like "MyService"
- * @param serviceType the service type like "_test._tcp"
- * @param subtypes the service subtypes like "_sub1"
- * @param port the port number in range [1, 65535]
- * @param txtMap the map of TXT names and values
- * @throws TimeoutException if the service isn't registered within timeout
- */
- public void addSrpService(
- String serviceName,
- String serviceType,
- List<String> subtypes,
- int port,
- Map<String, byte[]> txtMap)
- throws TimeoutException {
- StringBuilder fullServiceType = new StringBuilder(serviceType);
- for (String subtype : subtypes) {
- fullServiceType.append(",").append(subtype);
- }
- executeCommand(
- "srp client service add %s %s %d %d %d %s",
- serviceName,
- fullServiceType,
- port,
- 0 /* priority */,
- 0 /* weight */,
- txtMapToHexString(txtMap));
- waitFor(() -> isSrpServiceRegistered(serviceName, serviceType), SERVICE_DISCOVERY_TIMEOUT);
- }
-
- /**
- * Removes an SRP service for the SRP client.
- *
- * @param serviceName the service name like "MyService"
- * @param serviceType the service type like "_test._tcp"
- * @param notifyServer whether to notify SRP server about the removal
- */
- public void removeSrpService(String serviceName, String serviceType, boolean notifyServer) {
- String verb = notifyServer ? "remove" : "clear";
- executeCommand("srp client service %s %s %s", verb, serviceName, serviceType);
- }
-
- /**
- * Updates an existing SRP service for the SRP client.
- *
- * <p>This is essentially a 'remove' and an 'add' on the SRP client's side.
- *
- * @param serviceName the service name like "MyService"
- * @param serviceType the service type like "_test._tcp"
- * @param subtypes the service subtypes like "_sub1"
- * @param port the port number in range [1, 65535]
- * @param txtMap the map of TXT names and values
- * @throws TimeoutException if the service isn't updated within timeout
- */
- public void updateSrpService(
- String serviceName,
- String serviceType,
- List<String> subtypes,
- int port,
- Map<String, byte[]> txtMap)
- throws TimeoutException {
- removeSrpService(serviceName, serviceType, false /* notifyServer */);
- addSrpService(serviceName, serviceType, subtypes, port, txtMap);
- }
-
- /** Checks if an SRP service is registered. */
- public boolean isSrpServiceRegistered(String serviceName, String serviceType) {
- List<String> lines = executeCommand("srp client service");
- for (String line : lines) {
- if (line.contains(serviceName) && line.contains(serviceType)) {
- return line.contains("Registered");
- }
- }
- return false;
- }
-
- /** Checks if an SRP host is registered. */
- public boolean isSrpHostRegistered() {
- List<String> lines = executeCommand("srp client host");
- for (String line : lines) {
- return line.contains("Registered");
- }
- return false;
- }
-
/** Runs the "factoryreset" command on the device. */
public void factoryReset() {
try {
@@ -356,11 +240,6 @@
ping(address, null, 100 /* size */, 1 /* count */);
}
- @FormatMethod
- private List<String> executeCommand(String commandFormat, Object... args) {
- return executeCommand(String.format(commandFormat, args));
- }
-
private List<String> executeCommand(String command) {
try {
mWriter.write(command + "\n");
@@ -384,7 +263,7 @@
if (line.equals("Done")) {
break;
}
- if (line.startsWith("Error")) {
+ if (line.startsWith("Error:")) {
fail("ot-cli-ftd reported an error: " + line);
}
if (!line.startsWith("> ")) {
@@ -393,27 +272,4 @@
}
return result;
}
-
- private static String txtMapToHexString(Map<String, byte[]> txtMap) {
- if (txtMap == null) {
- return "";
- }
- StringBuilder sb = new StringBuilder();
- for (Map.Entry<String, byte[]> entry : txtMap.entrySet()) {
- int length = entry.getKey().length() + entry.getValue().length + 1;
- sb.append(String.format("%02x", length));
- sb.append(toHexString(entry.getKey()));
- sb.append(toHexString("="));
- sb.append(toHexString(entry.getValue()));
- }
- return sb.toString();
- }
-
- private static String toHexString(String s) {
- return toHexString(s.getBytes(StandardCharsets.UTF_8));
- }
-
- private static String toHexString(byte[] bytes) {
- return base16().encode(bytes);
- }
}
diff --git a/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java b/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java
index 6e70d24..74251a6 100644
--- a/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java
+++ b/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.java
@@ -23,18 +23,12 @@
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
import android.net.TestNetworkInterface;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
import android.net.thread.ThreadNetworkController;
import android.os.Handler;
import android.os.SystemClock;
import android.os.SystemProperties;
-import androidx.annotation.NonNull;
-
import com.android.net.module.util.Struct;
import com.android.net.module.util.structs.Icmpv6Header;
import com.android.net.module.util.structs.Ipv6Header;
@@ -57,7 +51,6 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -73,7 +66,6 @@
public static final Duration JOIN_TIMEOUT = Duration.ofSeconds(30);
public static final Duration LEAVE_TIMEOUT = Duration.ofSeconds(2);
public static final Duration CALLBACK_TIMEOUT = Duration.ofSeconds(1);
- public static final Duration SERVICE_DISCOVERY_TIMEOUT = Duration.ofSeconds(20);
private IntegrationTestUtils() {}
@@ -297,106 +289,4 @@
}
return false;
}
-
- /** Return the first discovered service of {@code serviceType}. */
- public static NsdServiceInfo discoverService(NsdManager nsdManager, String serviceType)
- throws Exception {
- CompletableFuture<NsdServiceInfo> serviceInfoFuture = new CompletableFuture<>();
- NsdManager.DiscoveryListener listener =
- new DefaultDiscoveryListener() {
- @Override
- public void onServiceFound(NsdServiceInfo serviceInfo) {
- serviceInfoFuture.complete(serviceInfo);
- }
- };
- nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, listener);
- try {
- serviceInfoFuture.get(SERVICE_DISCOVERY_TIMEOUT.toMillis(), MILLISECONDS);
- } finally {
- nsdManager.stopServiceDiscovery(listener);
- }
-
- return serviceInfoFuture.get();
- }
-
- /**
- * Returns the {@link NsdServiceInfo} when a service instance of {@code serviceType} gets lost.
- */
- public static NsdManager.DiscoveryListener discoverForServiceLost(
- NsdManager nsdManager,
- String serviceType,
- CompletableFuture<NsdServiceInfo> serviceInfoFuture) {
- NsdManager.DiscoveryListener listener =
- new DefaultDiscoveryListener() {
- @Override
- public void onServiceLost(NsdServiceInfo serviceInfo) {
- serviceInfoFuture.complete(serviceInfo);
- }
- };
- nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, listener);
- return listener;
- }
-
- /** Resolves the service. */
- public static NsdServiceInfo resolveService(NsdManager nsdManager, NsdServiceInfo serviceInfo)
- throws Exception {
- return resolveServiceUntil(nsdManager, serviceInfo, s -> true);
- }
-
- /** Returns the first resolved service that satisfies the {@code predicate}. */
- public static NsdServiceInfo resolveServiceUntil(
- NsdManager nsdManager, NsdServiceInfo serviceInfo, Predicate<NsdServiceInfo> predicate)
- throws Exception {
- CompletableFuture<NsdServiceInfo> resolvedServiceInfoFuture = new CompletableFuture<>();
- NsdManager.ServiceInfoCallback callback =
- new DefaultServiceInfoCallback() {
- @Override
- public void onServiceUpdated(@NonNull NsdServiceInfo serviceInfo) {
- if (predicate.test(serviceInfo)) {
- resolvedServiceInfoFuture.complete(serviceInfo);
- }
- }
- };
- nsdManager.registerServiceInfoCallback(serviceInfo, directExecutor(), callback);
- try {
- return resolvedServiceInfoFuture.get(
- SERVICE_DISCOVERY_TIMEOUT.toMillis(), MILLISECONDS);
- } finally {
- nsdManager.unregisterServiceInfoCallback(callback);
- }
- }
-
- private static class DefaultDiscoveryListener implements NsdManager.DiscoveryListener {
- @Override
- public void onStartDiscoveryFailed(String serviceType, int errorCode) {}
-
- @Override
- public void onStopDiscoveryFailed(String serviceType, int errorCode) {}
-
- @Override
- public void onDiscoveryStarted(String serviceType) {}
-
- @Override
- public void onDiscoveryStopped(String serviceType) {}
-
- @Override
- public void onServiceFound(NsdServiceInfo serviceInfo) {}
-
- @Override
- public void onServiceLost(NsdServiceInfo serviceInfo) {}
- }
-
- private static class DefaultServiceInfoCallback implements NsdManager.ServiceInfoCallback {
- @Override
- public void onServiceInfoCallbackRegistrationFailed(int errorCode) {}
-
- @Override
- public void onServiceUpdated(@NonNull NsdServiceInfo serviceInfo) {}
-
- @Override
- public void onServiceLost() {}
-
- @Override
- public void onServiceInfoCallbackUnregistered() {}
- }
}
diff --git a/thread/tests/unit/src/com/android/server/thread/NsdPublisherTest.java b/thread/tests/unit/src/com/android/server/thread/NsdPublisherTest.java
index 54e89b1..8aea0a3 100644
--- a/thread/tests/unit/src/com/android/server/thread/NsdPublisherTest.java
+++ b/thread/tests/unit/src/com/android/server/thread/NsdPublisherTest.java
@@ -28,7 +28,6 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import android.net.InetAddresses;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.os.Handler;
@@ -43,8 +42,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.net.InetAddress;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -285,189 +282,6 @@
}
@Test
- public void registerHost_nsdManagerSucceeds_serviceRegistrationSucceeds() throws Exception {
- prepareTest();
-
- mNsdPublisher.registerHost(
- "MyHost",
- List.of("2001:db8::1", "2001:db8::2", "2001:db8::3"),
- mRegistrationReceiver,
- 16 /* listenerId */);
-
- mTestLooper.dispatchAll();
-
- ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
- ArgumentCaptor.forClass(NsdServiceInfo.class);
- ArgumentCaptor<NsdManager.RegistrationListener> actualRegistrationListenerCaptor =
- ArgumentCaptor.forClass(NsdManager.RegistrationListener.class);
-
- verify(mMockNsdManager, times(1))
- .registerService(
- actualServiceInfoCaptor.capture(),
- eq(PROTOCOL_DNS_SD),
- any(),
- actualRegistrationListenerCaptor.capture());
-
- NsdServiceInfo actualServiceInfo = actualServiceInfoCaptor.getValue();
- NsdManager.RegistrationListener actualRegistrationListener =
- actualRegistrationListenerCaptor.getValue();
-
- actualRegistrationListener.onServiceRegistered(actualServiceInfo);
- mTestLooper.dispatchAll();
-
- assertThat(actualServiceInfo.getServiceName()).isNull();
- assertThat(actualServiceInfo.getServiceType()).isNull();
- assertThat(actualServiceInfo.getSubtypes()).isEmpty();
- assertThat(actualServiceInfo.getPort()).isEqualTo(0);
- assertThat(actualServiceInfo.getAttributes()).isEmpty();
- assertThat(actualServiceInfo.getHostname()).isEqualTo("MyHost");
- assertThat(actualServiceInfo.getHostAddresses())
- .isEqualTo(makeAddresses("2001:db8::1", "2001:db8::2", "2001:db8::3"));
-
- verify(mRegistrationReceiver, times(1)).onSuccess();
- }
-
- @Test
- public void registerHost_nsdManagerFails_serviceRegistrationFails() throws Exception {
- prepareTest();
-
- mNsdPublisher.registerHost(
- "MyHost",
- List.of("2001:db8::1", "2001:db8::2", "2001:db8::3"),
- mRegistrationReceiver,
- 16 /* listenerId */);
-
- mTestLooper.dispatchAll();
-
- ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
- ArgumentCaptor.forClass(NsdServiceInfo.class);
- ArgumentCaptor<NsdManager.RegistrationListener> actualRegistrationListenerCaptor =
- ArgumentCaptor.forClass(NsdManager.RegistrationListener.class);
-
- verify(mMockNsdManager, times(1))
- .registerService(
- actualServiceInfoCaptor.capture(),
- eq(PROTOCOL_DNS_SD),
- any(),
- actualRegistrationListenerCaptor.capture());
- mTestLooper.dispatchAll();
-
- NsdServiceInfo actualServiceInfo = actualServiceInfoCaptor.getValue();
- NsdManager.RegistrationListener actualRegistrationListener =
- actualRegistrationListenerCaptor.getValue();
-
- actualRegistrationListener.onRegistrationFailed(actualServiceInfo, FAILURE_INTERNAL_ERROR);
- mTestLooper.dispatchAll();
-
- assertThat(actualServiceInfo.getServiceName()).isNull();
- assertThat(actualServiceInfo.getServiceType()).isNull();
- assertThat(actualServiceInfo.getSubtypes()).isEmpty();
- assertThat(actualServiceInfo.getPort()).isEqualTo(0);
- assertThat(actualServiceInfo.getAttributes()).isEmpty();
- assertThat(actualServiceInfo.getHostname()).isEqualTo("MyHost");
- assertThat(actualServiceInfo.getHostAddresses())
- .isEqualTo(makeAddresses("2001:db8::1", "2001:db8::2", "2001:db8::3"));
-
- verify(mRegistrationReceiver, times(1)).onError(FAILURE_INTERNAL_ERROR);
- }
-
- @Test
- public void registerHost_nsdManagerThrows_serviceRegistrationFails() throws Exception {
- prepareTest();
-
- doThrow(new IllegalArgumentException("NsdManager fails"))
- .when(mMockNsdManager)
- .registerService(any(), anyInt(), any(Executor.class), any());
-
- mNsdPublisher.registerHost(
- "MyHost",
- List.of("2001:db8::1", "2001:db8::2", "2001:db8::3"),
- mRegistrationReceiver,
- 16 /* listenerId */);
-
- mTestLooper.dispatchAll();
-
- verify(mRegistrationReceiver, times(1)).onError(FAILURE_INTERNAL_ERROR);
- }
-
- @Test
- public void unregisterHost_nsdManagerSucceeds_serviceUnregistrationSucceeds() throws Exception {
- prepareTest();
-
- mNsdPublisher.registerHost(
- "MyHost",
- List.of("2001:db8::1", "2001:db8::2", "2001:db8::3"),
- mRegistrationReceiver,
- 16 /* listenerId */);
-
- mTestLooper.dispatchAll();
-
- ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
- ArgumentCaptor.forClass(NsdServiceInfo.class);
- ArgumentCaptor<NsdManager.RegistrationListener> actualRegistrationListenerCaptor =
- ArgumentCaptor.forClass(NsdManager.RegistrationListener.class);
-
- verify(mMockNsdManager, times(1))
- .registerService(
- actualServiceInfoCaptor.capture(),
- eq(PROTOCOL_DNS_SD),
- any(Executor.class),
- actualRegistrationListenerCaptor.capture());
-
- NsdServiceInfo actualServiceInfo = actualServiceInfoCaptor.getValue();
- NsdManager.RegistrationListener actualRegistrationListener =
- actualRegistrationListenerCaptor.getValue();
-
- actualRegistrationListener.onServiceRegistered(actualServiceInfo);
- mNsdPublisher.unregister(mUnregistrationReceiver, 16 /* listenerId */);
- mTestLooper.dispatchAll();
- verify(mMockNsdManager, times(1)).unregisterService(actualRegistrationListener);
-
- actualRegistrationListener.onServiceUnregistered(actualServiceInfo);
- mTestLooper.dispatchAll();
- verify(mUnregistrationReceiver, times(1)).onSuccess();
- }
-
- @Test
- public void unregisterHost_nsdManagerFails_serviceUnregistrationFails() throws Exception {
- prepareTest();
-
- mNsdPublisher.registerHost(
- "MyHost",
- List.of("2001:db8::1", "2001:db8::2", "2001:db8::3"),
- mRegistrationReceiver,
- 16 /* listenerId */);
-
- mTestLooper.dispatchAll();
-
- ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
- ArgumentCaptor.forClass(NsdServiceInfo.class);
- ArgumentCaptor<NsdManager.RegistrationListener> actualRegistrationListenerCaptor =
- ArgumentCaptor.forClass(NsdManager.RegistrationListener.class);
-
- verify(mMockNsdManager, times(1))
- .registerService(
- actualServiceInfoCaptor.capture(),
- eq(PROTOCOL_DNS_SD),
- any(Executor.class),
- actualRegistrationListenerCaptor.capture());
-
- NsdServiceInfo actualServiceInfo = actualServiceInfoCaptor.getValue();
- NsdManager.RegistrationListener actualRegistrationListener =
- actualRegistrationListenerCaptor.getValue();
-
- actualRegistrationListener.onServiceRegistered(actualServiceInfo);
- mNsdPublisher.unregister(mUnregistrationReceiver, 16 /* listenerId */);
- mTestLooper.dispatchAll();
- verify(mMockNsdManager, times(1)).unregisterService(actualRegistrationListener);
-
- actualRegistrationListener.onUnregistrationFailed(
- actualServiceInfo, FAILURE_INTERNAL_ERROR);
- mTestLooper.dispatchAll();
- verify(mUnregistrationReceiver, times(1)).onError(0);
- }
-
- @Test
public void onOtDaemonDied_unregisterAll() {
prepareTest();
@@ -522,30 +336,11 @@
actualRegistrationListenerCaptor.getAllValues().get(1);
actualListener2.onServiceRegistered(actualServiceInfoCaptor.getValue());
- mNsdPublisher.registerHost(
- "Myhost",
- List.of("2001:db8::1", "2001:db8::2", "2001:db8::3"),
- mRegistrationReceiver,
- 18 /* listenerId */);
-
- mTestLooper.dispatchAll();
-
- verify(mMockNsdManager, times(3))
- .registerService(
- actualServiceInfoCaptor.capture(),
- eq(PROTOCOL_DNS_SD),
- any(Executor.class),
- actualRegistrationListenerCaptor.capture());
- NsdManager.RegistrationListener actualListener3 =
- actualRegistrationListenerCaptor.getAllValues().get(1);
- actualListener3.onServiceRegistered(actualServiceInfoCaptor.getValue());
-
mNsdPublisher.onOtDaemonDied();
mTestLooper.dispatchAll();
verify(mMockNsdManager, times(1)).unregisterService(actualListener1);
verify(mMockNsdManager, times(1)).unregisterService(actualListener2);
- verify(mMockNsdManager, times(1)).unregisterService(actualListener3);
}
private static DnsTxtAttribute makeTxtAttribute(String name, List<Integer> value) {
@@ -561,15 +356,6 @@
return txtAttribute;
}
- private static List<InetAddress> makeAddresses(String... addressStrings) {
- List<InetAddress> addresses = new ArrayList<>();
-
- for (String addressString : addressStrings) {
- addresses.add(InetAddresses.parseNumericAddress(addressString));
- }
- return addresses;
- }
-
// @Before and @Test run in different threads. NsdPublisher requires the jobs are run on the
// thread looper, so TestLooper needs to be created inside each test case to install the
// correct looper.