diff --git a/framework-t/api/current.txt b/framework-t/api/current.txt index b5d3bceec8..7977cc54e0 100644 --- a/framework-t/api/current.txt +++ b/framework-t/api/current.txt @@ -4,6 +4,7 @@ package android.net.nsd { public final class NsdManager { method public void discoverServices(String, int, android.net.nsd.NsdManager.DiscoveryListener); method public void discoverServices(@NonNull String, int, @Nullable android.net.Network, @NonNull android.net.nsd.NsdManager.DiscoveryListener); + method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void discoverServices(@NonNull String, int, @NonNull android.net.NetworkRequest, @NonNull android.net.nsd.NsdManager.DiscoveryListener); method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener); method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener); method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener); diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt index 4c06a1eb44..9506081e6c 100644 --- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt +++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt @@ -264,21 +264,27 @@ class NsdManagerTest { .addTransportType(TRANSPORT_TEST) .setNetworkSpecifier(testNetworkSpecifier) .build(), cb) + val agent = registerTestNetworkAgent(iface.interfaceName) + val network = agent.network ?: fail("Registered agent should have a network") + // The network has no INTERNET capability, so will be marked validated immediately + cb.expectAvailableThenValidatedCallbacks(network) + return TestTapNetwork(iface, cb, agent, network) + } + + private fun registerTestNetworkAgent(ifaceName: String): TestableNetworkAgent { val agent = TestableNetworkAgent(context, handlerThread.looper, NetworkCapabilities().apply { removeCapability(NET_CAPABILITY_TRUSTED) addTransportType(TRANSPORT_TEST) - setNetworkSpecifier(testNetworkSpecifier) + setNetworkSpecifier(TestNetworkSpecifier(ifaceName)) }, LinkProperties().apply { - interfaceName = iface.interfaceName + interfaceName = ifaceName }, NetworkAgentConfig.Builder().build()) - val network = agent.register() + agent.register() agent.markConnected() - // The network has no INTERNET capability, so will be marked validated immediately - cb.expectAvailableThenValidatedCallbacks(network) - return TestTapNetwork(iface, cb, agent, network) + return agent } @After @@ -434,6 +440,71 @@ class NsdManagerTest { } } + @Test + fun testNsdManager_DiscoverWithNetworkRequest() { + // This tests requires shims supporting T+ APIs (discovering on network request) + assumeTrue(ConstantsShim.VERSION > SC_V2) + + val si = NsdServiceInfo() + si.serviceType = SERVICE_TYPE + si.serviceName = this.serviceName + si.port = 12345 // Test won't try to connect so port does not matter + + val registrationRecord = NsdRegistrationRecord() + val registeredInfo1 = registerService(registrationRecord, si) + val discoveryRecord = NsdDiscoveryRecord() + + tryTest { + val specifier = TestNetworkSpecifier(testNetwork1.iface.interfaceName) + nsdShim.discoverServices(nsdManager, SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, + NetworkRequest.Builder() + .removeCapability(NET_CAPABILITY_TRUSTED) + .addTransportType(TRANSPORT_TEST) + .setNetworkSpecifier(specifier) + .build(), + discoveryRecord) + + val discoveryStarted = discoveryRecord.expectCallback() + assertEquals(SERVICE_TYPE, discoveryStarted.serviceType) + + val serviceDiscovered = discoveryRecord.expectCallback() + assertEquals(registeredInfo1.serviceName, serviceDiscovered.serviceInfo.serviceName) + assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceDiscovered.serviceInfo)) + + // Unregister, then register the service back: it should be lost and found again + nsdManager.unregisterService(registrationRecord) + val serviceLost1 = discoveryRecord.expectCallback() + assertEquals(registeredInfo1.serviceName, serviceLost1.serviceInfo.serviceName) + assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceLost1.serviceInfo)) + + registrationRecord.expectCallback() + val registeredInfo2 = registerService(registrationRecord, si) + val serviceDiscovered2 = discoveryRecord.expectCallback() + assertEquals(registeredInfo2.serviceName, serviceDiscovered2.serviceInfo.serviceName) + assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceDiscovered2.serviceInfo)) + + // Teardown, then bring back up a network on the test interface: the service should + // go away, then come back + testNetwork1.agent.unregister() + val serviceLost = discoveryRecord.expectCallback() + assertEquals(registeredInfo2.serviceName, serviceLost.serviceInfo.serviceName) + assertEquals(testNetwork1.network, nsdShim.getNetwork(serviceLost.serviceInfo)) + + val newAgent = runAsShell(MANAGE_TEST_NETWORKS) { + registerTestNetworkAgent(testNetwork1.iface.interfaceName) + } + val newNetwork = newAgent.network ?: fail("Registered agent should have a network") + val serviceDiscovered3 = discoveryRecord.expectCallback() + assertEquals(registeredInfo2.serviceName, serviceDiscovered3.serviceInfo.serviceName) + assertEquals(newNetwork, nsdShim.getNetwork(serviceDiscovered3.serviceInfo)) + } cleanupStep { + nsdManager.stopServiceDiscovery(discoveryRecord) + discoveryRecord.expectCallback() + } cleanup { + nsdManager.unregisterService(registrationRecord) + } + } + @Test fun testNsdManager_ResolveOnNetwork() { // This tests requires shims supporting T+ APIs (NsdServiceInfo.network)