Merge "Add test for service callback"
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index b7eb009..66e7713 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -44,6 +44,11 @@
import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.ResolveStopped
import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.ServiceResolved
import android.net.cts.NsdManagerTest.NsdResolveRecord.ResolveEvent.StopResolutionFailed
+import android.net.cts.NsdManagerTest.NsdServiceInfoCallbackRecord.ServiceInfoCallbackEvent.RegisterCallbackFailed
+import android.net.cts.NsdManagerTest.NsdServiceInfoCallbackRecord.ServiceInfoCallbackEvent.ServiceUpdated
+import android.net.cts.NsdManagerTest.NsdServiceInfoCallbackRecord.ServiceInfoCallbackEvent.ServiceUpdatedLost
+import android.net.cts.NsdManagerTest.NsdServiceInfoCallbackRecord.ServiceInfoCallbackEvent.UnregisterCallbackSucceeded
+import android.net.cts.util.CtsNetUtils
import android.net.nsd.NsdManager
import android.net.nsd.NsdManager.DiscoveryListener
import android.net.nsd.NsdManager.RegistrationListener
@@ -60,6 +65,7 @@
import com.android.net.module.util.ArrayTrackRecord
import com.android.net.module.util.TrackRecord
import com.android.networkstack.apishim.NsdShimImpl
+import com.android.networkstack.apishim.common.NsdShim
import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.TestableNetworkAgent
@@ -115,6 +121,7 @@
private val serviceName = "NsdTest%09d".format(Random().nextInt(1_000_000_000))
private val serviceType = "_nmt%09d._tcp".format(Random().nextInt(1_000_000_000))
private val handlerThread = HandlerThread(NsdManagerTest::class.java.simpleName)
+ private val ctsNetUtils by lazy{ CtsNetUtils(context) }
private lateinit var testNetwork1: TestTapNetwork
private lateinit var testNetwork2: TestTapNetwork
@@ -157,7 +164,8 @@
inline fun <reified V : NsdEvent> expectCallback(timeoutMs: Long = TIMEOUT_MS): V {
val nextEvent = nextEvents.poll(timeoutMs)
- assertNotNull(nextEvent, "No callback received after $timeoutMs ms")
+ assertNotNull(nextEvent, "No callback received after $timeoutMs ms, expected " +
+ "${V::class.java.simpleName}")
assertTrue(nextEvent is V, "Expected ${V::class.java.simpleName} but got " +
nextEvent.javaClass.simpleName)
return nextEvent
@@ -287,6 +295,32 @@
}
}
+ private class NsdServiceInfoCallbackRecord : NsdShim.ServiceInfoCallbackShim,
+ NsdRecord<NsdServiceInfoCallbackRecord.ServiceInfoCallbackEvent>() {
+ sealed class ServiceInfoCallbackEvent : NsdEvent {
+ data class RegisterCallbackFailed(val errorCode: Int) : ServiceInfoCallbackEvent()
+ data class ServiceUpdated(val serviceInfo: NsdServiceInfo) : ServiceInfoCallbackEvent()
+ object ServiceUpdatedLost : ServiceInfoCallbackEvent()
+ object UnregisterCallbackSucceeded : ServiceInfoCallbackEvent()
+ }
+
+ override fun onServiceInfoCallbackRegistrationFailed(err: Int) {
+ add(RegisterCallbackFailed(err))
+ }
+
+ override fun onServiceUpdated(si: NsdServiceInfo) {
+ add(ServiceUpdated(si))
+ }
+
+ override fun onServiceLost() {
+ add(ServiceUpdatedLost)
+ }
+
+ override fun onServiceInfoCallbackUnregistered() {
+ add(UnregisterCallbackSucceeded)
+ }
+ }
+
@Before
fun setUp() {
handlerThread.start()
@@ -772,6 +806,64 @@
assertEquals(si.serviceType, stoppedCb.serviceInfo.serviceType)
}
+ @Test
+ fun testRegisterServiceInfoCallback() {
+ // This test requires shims supporting U+ APIs (NsdManager.subscribeService)
+ assumeTrue(TestUtils.shouldTestUApis())
+
+ // Ensure Wi-Fi network connected and get addresses
+ val wifiNetwork = ctsNetUtils.ensureWifiConnected()
+ val lp = cm.getLinkProperties(wifiNetwork)
+ assertNotNull(lp)
+ val addresses = lp.addresses
+ assertFalse(addresses.isEmpty())
+
+ val si = NsdServiceInfo().apply {
+ serviceType = this@NsdManagerTest.serviceType
+ serviceName = this@NsdManagerTest.serviceName
+ network = wifiNetwork
+ port = 12345 // Test won't try to connect so port does not matter
+ }
+
+ // Register service on Wi-Fi network
+ val registrationRecord = NsdRegistrationRecord()
+ registerService(registrationRecord, si)
+
+ val discoveryRecord = NsdDiscoveryRecord()
+ val cbRecord = NsdServiceInfoCallbackRecord()
+ tryTest {
+ // Discover service on Wi-Fi network.
+ nsdShim.discoverServices(nsdManager, serviceType, NsdManager.PROTOCOL_DNS_SD,
+ wifiNetwork, Executor { it.run() }, discoveryRecord)
+ val foundInfo = discoveryRecord.waitForServiceDiscovered(
+ serviceName, wifiNetwork)
+
+ // Subscribe to service and check the addresses are the same as Wi-Fi addresses
+ nsdShim.registerServiceInfoCallback(nsdManager, foundInfo, { it.run() }, cbRecord)
+ for (i in addresses.indices) {
+ val subscribeCb = cbRecord.expectCallback<ServiceUpdated>()
+ assertEquals(foundInfo.serviceName, subscribeCb.serviceInfo.serviceName)
+ val hostAddresses = subscribeCb.serviceInfo.hostAddresses
+ assertEquals(i + 1, hostAddresses.size)
+ for (hostAddress in hostAddresses) {
+ assertTrue(addresses.contains(hostAddress))
+ }
+ }
+ } cleanupStep {
+ nsdManager.unregisterService(registrationRecord)
+ registrationRecord.expectCallback<ServiceUnregistered>()
+ discoveryRecord.expectCallback<ServiceLost>()
+ cbRecord.expectCallback<ServiceUpdatedLost>()
+ } cleanupStep {
+ // Cancel subscription and check stop callback received.
+ nsdShim.unregisterServiceInfoCallback(nsdManager, cbRecord)
+ cbRecord.expectCallback<UnregisterCallbackSucceeded>()
+ } cleanup {
+ nsdManager.stopServiceDiscovery(discoveryRecord)
+ discoveryRecord.expectCallback<DiscoveryStopped>()
+ }
+ }
+
/**
* Register a service and return its registration record.
*/