[mdns] allow only one registration to have addresses for a hostname

This is to simplify the management of registrations of custom hosts.

Bug: 333630227
Change-Id: I183de590a6362e53b10a1aa42b723dcae0ffde00
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java b/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
index 98c2d86..42efcac 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
@@ -448,10 +448,11 @@
         /**
          * Get the ID of a conflicting registration due to host, or -1 if none.
          *
-         * <p>It's valid that multiple registrations from the same user are using the same hostname.
-         *
          * <p>If there's already another registration with the same hostname requested by another
-         * user, this is considered a conflict.
+         * user, this is a conflict.
+         *
+         * <p>If there're two registrations both containing address records using the same hostname,
+         * this is a conflict.
          */
         int getConflictingRegistrationDueToHost(@NonNull NsdServiceInfo info, int clientUid) {
             if (TextUtils.isEmpty(info.getHostname())) {
@@ -460,10 +461,17 @@
             for (int i = 0; i < mPendingRegistrations.size(); i++) {
                 final Registration otherRegistration = mPendingRegistrations.valueAt(i);
                 final NsdServiceInfo otherInfo = otherRegistration.getServiceInfo();
+                final int otherServiceId = mPendingRegistrations.keyAt(i);
                 if (clientUid != otherRegistration.mClientUid
                         && MdnsUtils.equalsIgnoreDnsCase(
                                 info.getHostname(), otherInfo.getHostname())) {
-                    return mPendingRegistrations.keyAt(i);
+                    return otherServiceId;
+                }
+                if (!info.getHostAddresses().isEmpty()
+                        && !otherInfo.getHostAddresses().isEmpty()
+                        && MdnsUtils.equalsIgnoreDnsCase(
+                                info.getHostname(), otherInfo.getHostname())) {
+                    return otherServiceId;
                 }
             }
             return -1;
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 28685cc..6394599 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -130,6 +130,7 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import kotlin.test.assertNotEquals
 
 private const val TAG = "NsdManagerTest"
 private const val TIMEOUT_MS = 2000L
@@ -2037,7 +2038,7 @@
     }
 
     @Test
-    fun testAdvertisingAndDiscovery_multipleRegistrationsForSameCustomHost_unionOfAddressesFound() {
+    fun testAdvertisingAndDiscovery_multipleRegistrationsForSameCustomHost_hostRenamed() {
         val hostAddresses1 = listOf(
                 parseNumericAddress("192.0.2.23"),
                 parseNumericAddress("2001:db8::1"),
@@ -2045,9 +2046,6 @@
         val hostAddresses2 = listOf(
                 parseNumericAddress("192.0.2.24"),
                 parseNumericAddress("2001:db8::3"))
-        val hostAddresses3 = listOf(
-                parseNumericAddress("2001:db8::3"),
-                parseNumericAddress("2001:db8::5"))
         val si1 = NsdServiceInfo().also {
             it.network = testNetwork1.network
             it.hostname = customHostname
@@ -2061,18 +2059,9 @@
             it.hostname = customHostname
             it.hostAddresses = hostAddresses2
         }
-        val si3 = NsdServiceInfo().also {
-            it.network = testNetwork1.network
-            it.serviceName = serviceName3
-            it.serviceType = serviceType
-            it.port = TEST_PORT + 1
-            it.hostname = customHostname
-            it.hostAddresses = hostAddresses3
-        }
 
         val registrationRecord1 = NsdRegistrationRecord()
         val registrationRecord2 = NsdRegistrationRecord()
-        val registrationRecord3 = NsdRegistrationRecord()
 
         val discoveryRecord = NsdDiscoveryRecord()
         tryTest {
@@ -2082,27 +2071,13 @@
             nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD,
                     testNetwork1.network, Executor { it.run() }, discoveryRecord)
 
-            val discoveredInfo1 = discoveryRecord.waitForServiceDiscovered(
+            val discoveredInfo = discoveryRecord.waitForServiceDiscovered(
                     serviceName, serviceType, testNetwork1.network)
-            val resolvedInfo1 = resolveService(discoveredInfo1)
+            val resolvedInfo = resolveService(discoveredInfo)
 
-            assertEquals(TEST_PORT, resolvedInfo1.port)
-            assertEquals(si1.hostname, resolvedInfo1.hostname)
-            assertAddressEquals(
-                    hostAddresses1 + hostAddresses2,
-                    resolvedInfo1.hostAddresses)
-
-            registerService(registrationRecord3, si3)
-
-            val discoveredInfo2 = discoveryRecord.waitForServiceDiscovered(
-                    serviceName3, serviceType, testNetwork1.network)
-            val resolvedInfo2 = resolveService(discoveredInfo2)
-
-            assertEquals(TEST_PORT + 1, resolvedInfo2.port)
-            assertEquals(si2.hostname, resolvedInfo2.hostname)
-            assertAddressEquals(
-                    hostAddresses1 + hostAddresses2 + hostAddresses3,
-                    resolvedInfo2.hostAddresses)
+            assertEquals(TEST_PORT, resolvedInfo.port)
+            assertNotEquals(si1.hostname, resolvedInfo.hostname)
+            assertAddressEquals(hostAddresses2, resolvedInfo.hostAddresses)
         } cleanupStep {
             nsdManager.stopServiceDiscovery(discoveryRecord)
 
@@ -2110,7 +2085,6 @@
         } cleanup {
             nsdManager.unregisterService(registrationRecord1)
             nsdManager.unregisterService(registrationRecord2)
-            nsdManager.unregisterService(registrationRecord3)
         }
     }