diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 8e06fde..3bc09db 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -763,6 +763,7 @@
                             final MdnsSearchOptions options = MdnsSearchOptions.newBuilder()
                                     .setNetwork(info.getNetwork())
                                     .setIsPassiveMode(true)
+                                    .setResolveInstanceName(info.getServiceName())
                                     .build();
                             mMdnsDiscoveryManager.registerListener(
                                     resolveServiceType, listener, options);
@@ -775,7 +776,7 @@
                             }
 
                             maybeStartDaemon();
-                            if (resolveService(id, args.serviceInfo)) {
+                            if (resolveService(id, info)) {
                                 clientInfo.mResolvedService = new NsdServiceInfo();
                                 storeLegacyRequestMap(clientId, id, clientInfo, msg.what);
                             } else {
diff --git a/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java b/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java
index c472a8f..9a67007 100644
--- a/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java
+++ b/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java
@@ -120,21 +120,17 @@
             // List of (name, type) to query
             final ArrayList<Pair<String[], Integer>> missingKnownAnswerRecords = new ArrayList<>();
             for (MdnsResponse response : servicesToResolve) {
-                // In practice responses should always have at least one pointer record, since the
-                // record is added after creation in MdnsResponseDecoder. All PTR records point to
-                // the same instance name, since addPointerRecord is only called on instances
-                // obtained through MdnsResponseDecoder.findResponseWithPointer.
                 // TODO: also send queries to renew record TTL (as per RFC6762 7.1 no need to query
                 // if remaining TTL is more than half the original one, so send the queries if half
                 // the TTL has passed).
-                if (!response.hasPointerRecords() || response.isComplete()) continue;
-                final String[] instanceName = response.getPointerRecords().get(0).getPointer();
-                if (instanceName == null) continue;
+                if (response.isComplete()) continue;
+                final String[] serviceName = response.getServiceName();
+                if (serviceName == null) continue;
                 if (!response.hasTextRecord()) {
-                    missingKnownAnswerRecords.add(new Pair<>(instanceName, MdnsRecord.TYPE_TXT));
+                    missingKnownAnswerRecords.add(new Pair<>(serviceName, MdnsRecord.TYPE_TXT));
                 }
                 if (!response.hasServiceRecord()) {
-                    missingKnownAnswerRecords.add(new Pair<>(instanceName, MdnsRecord.TYPE_SRV));
+                    missingKnownAnswerRecords.add(new Pair<>(serviceName, MdnsRecord.TYPE_SRV));
                     // The hostname is not yet known, so queries for address records will be sent
                     // the next time the EnqueueMdnsQueryCallable is enqueued if the reply does not
                     // contain them. In practice, advertisers should include the address records
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java b/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java
index 3a41978..a6e3762 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java
@@ -16,16 +16,19 @@
 
 package com.android.server.connectivity.mdns;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.net.Network;
 
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Objects;
 
 /** An mDNS response. */
 public class MdnsResponse {
@@ -38,37 +41,65 @@
     private long lastUpdateTime;
     private final int interfaceIndex;
     @Nullable private final Network network;
+    @NonNull private final String[] serviceName;
 
     /** Constructs a new, empty response. */
-    public MdnsResponse(long now, int interfaceIndex, @Nullable Network network) {
+    public MdnsResponse(long now, @NonNull String[] serviceName, int interfaceIndex,
+            @Nullable Network network) {
         lastUpdateTime = now;
         records = new LinkedList<>();
         pointerRecords = new LinkedList<>();
         this.interfaceIndex = interfaceIndex;
         this.network = network;
+        this.serviceName = serviceName;
     }
 
-    // This generic typed helper compares records for equality.
-    // Returns True if records are the same.
-    private <T> boolean recordsAreSame(T a, T b) {
-        return ((a == null) && (b == null)) || ((a != null) && (b != null) && a.equals(b));
+    public MdnsResponse(@NonNull MdnsResponse base) {
+        records = new ArrayList<>(base.records);
+        pointerRecords = new ArrayList<>(base.pointerRecords);
+        serviceRecord = base.serviceRecord;
+        textRecord = base.textRecord;
+        inet4AddressRecord = base.inet4AddressRecord;
+        inet6AddressRecord = base.inet6AddressRecord;
+        lastUpdateTime = base.lastUpdateTime;
+        serviceName = base.serviceName;
+        interfaceIndex = base.interfaceIndex;
+        network = base.network;
+    }
+
+    /**
+     * Compare records for equality, including their TTL.
+     *
+     * MdnsRecord#equals ignores TTL and receiptTimeMillis, but methods in this class need to update
+     * records when the TTL changes (especially for goodbye announcements).
+     */
+    private boolean recordsAreSame(MdnsRecord a, MdnsRecord b) {
+        if (!Objects.equals(a, b)) return false;
+        return a == null || a.getTtl() == b.getTtl();
     }
 
     /**
      * Adds a pointer record.
      *
      * @return <code>true</code> if the record was added, or <code>false</code> if a matching
-     * pointer
-     * record is already present in the response.
+     * pointer record is already present in the response with the same TTL.
      */
     public synchronized boolean addPointerRecord(MdnsPointerRecord pointerRecord) {
-        if (!pointerRecords.contains(pointerRecord)) {
-            pointerRecords.add(pointerRecord);
-            records.add(pointerRecord);
-            return true;
+        if (!Arrays.equals(serviceName, pointerRecord.getPointer())) {
+            throw new IllegalArgumentException(
+                    "Pointer records for different service names cannot be added");
         }
-
-        return false;
+        final int existing = pointerRecords.indexOf(pointerRecord);
+        if (existing >= 0) {
+            if (recordsAreSame(pointerRecord, pointerRecords.get(existing))) {
+                return false;
+            }
+            pointerRecords.remove(existing);
+            records.remove(existing);
+        }
+        pointerRecords.add(pointerRecord);
+        records.add(pointerRecord);
+        return true;
     }
 
     /** Gets the pointer records. */
@@ -178,6 +209,7 @@
         }
         if (this.inet4AddressRecord != null) {
             records.remove(this.inet4AddressRecord);
+            this.inet4AddressRecord = null;
         }
         if (newInet4AddressRecord != null && newInet4AddressRecord.getInet4Address() != null) {
             this.inet4AddressRecord = newInet4AddressRecord;
@@ -203,6 +235,7 @@
         }
         if (this.inet6AddressRecord != null) {
             records.remove(this.inet6AddressRecord);
+            this.inet6AddressRecord = null;
         }
         if (newInet6AddressRecord != null && newInet6AddressRecord.getInet6Address() != null) {
             this.inet6AddressRecord = newInet6AddressRecord;
@@ -242,87 +275,42 @@
     }
 
     /**
-     * Merges any records that are present in another response into this one.
+     * Drop address records if they are for a hostname that does not match the service record.
      *
-     * @return <code>true</code> if any records were added or updated.
+     * @return True if the records were dropped.
      */
-    public synchronized boolean mergeRecordsFrom(MdnsResponse other) {
-        lastUpdateTime = other.lastUpdateTime;
+    public synchronized boolean dropUnmatchedAddressRecords() {
+        if (this.serviceRecord == null) return false;
+        boolean dropAddressRecords = false;
 
-        boolean updated = false;
-
-        List<MdnsPointerRecord> pointerRecords = other.getPointerRecords();
-        if (pointerRecords != null) {
-            for (MdnsPointerRecord pointerRecord : pointerRecords) {
-                if (addPointerRecord(pointerRecord)) {
-                    updated = true;
-                }
+        if (this.inet4AddressRecord != null) {
+            if (!Arrays.equals(
+                    this.serviceRecord.getServiceHost(), this.inet4AddressRecord.getName())) {
+                dropAddressRecords = true;
+            }
+        }
+        if (this.inet6AddressRecord != null) {
+            if (!Arrays.equals(
+                    this.serviceRecord.getServiceHost(), this.inet6AddressRecord.getName())) {
+                dropAddressRecords = true;
             }
         }
 
-        MdnsServiceRecord serviceRecord = other.getServiceRecord();
-        if (serviceRecord != null) {
-            if (setServiceRecord(serviceRecord)) {
-                updated = true;
-            }
+        if (dropAddressRecords) {
+            setInet4AddressRecord(null);
+            setInet6AddressRecord(null);
+            return true;
         }
-
-        MdnsTextRecord textRecord = other.getTextRecord();
-        if (textRecord != null) {
-            if (setTextRecord(textRecord)) {
-                updated = true;
-            }
-        }
-
-        MdnsInetAddressRecord otherInet4AddressRecord = other.getInet4AddressRecord();
-        if (otherInet4AddressRecord != null && otherInet4AddressRecord.getInet4Address() != null) {
-            if (setInet4AddressRecord(otherInet4AddressRecord)) {
-                updated = true;
-            }
-        }
-
-        MdnsInetAddressRecord otherInet6AddressRecord = other.getInet6AddressRecord();
-        if (otherInet6AddressRecord != null && otherInet6AddressRecord.getInet6Address() != null) {
-            if (setInet6AddressRecord(otherInet6AddressRecord)) {
-                updated = true;
-            }
-        }
-
-        // If the hostname in the service record no longer matches the hostname in either of the
-        // address records, then drop the address records.
-        if (this.serviceRecord != null) {
-            boolean dropAddressRecords = false;
-
-            if (this.inet4AddressRecord != null) {
-                if (!Arrays.equals(
-                        this.serviceRecord.getServiceHost(), this.inet4AddressRecord.getName())) {
-                    dropAddressRecords = true;
-                }
-            }
-            if (this.inet6AddressRecord != null) {
-                if (!Arrays.equals(
-                        this.serviceRecord.getServiceHost(), this.inet6AddressRecord.getName())) {
-                    dropAddressRecords = true;
-                }
-            }
-
-            if (dropAddressRecords) {
-                setInet4AddressRecord(null);
-                setInet6AddressRecord(null);
-                updated = true;
-            }
-        }
-
-        return updated;
+        return false;
     }
 
     /**
-     * Tests if the response is complete. A response is considered complete if it contains PTR, SRV,
-     * TXT, and A (for IPv4) or AAAA (for IPv6) records.
+     * Tests if the response is complete. A response is considered complete if it contains SRV,
+     * TXT, and A (for IPv4) or AAAA (for IPv6) records. The service type->name mapping is always
+     * known when constructing a MdnsResponse, so this may return true when there is no PTR record.
      */
     public synchronized boolean isComplete() {
-        return !pointerRecords.isEmpty()
-                && (serviceRecord != null)
+        return (serviceRecord != null)
                 && (textRecord != null)
                 && (inet4AddressRecord != null || inet6AddressRecord != null);
     }
@@ -331,12 +319,14 @@
      * Returns the key for this response. The key uniquely identifies the response by its service
      * name.
      */
-    public synchronized String getServiceInstanceName() {
-        if (pointerRecords.isEmpty()) {
-            return null;
-        }
-        String[] pointers = pointerRecords.get(0).getPointer();
-        return ((pointers != null) && (pointers.length > 0)) ? pointers[0] : null;
+    @Nullable
+    public String getServiceInstanceName() {
+        return serviceName.length > 0 ? serviceName[0] : null;
+    }
+
+    @NonNull
+    public String[] getServiceName() {
+        return serviceName;
     }
 
     /**
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java b/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
index 31527c0..7878b0b 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
@@ -20,17 +20,18 @@
 import android.annotation.Nullable;
 import android.net.Network;
 import android.os.SystemClock;
+import android.util.ArraySet;
 
 import com.android.server.connectivity.mdns.util.MdnsLogger;
 
 import java.io.EOFException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 
 /** A class that decodes mDNS responses from UDP packets. */
 public class MdnsResponseDecoder {
-
     public static final int SUCCESS = 0;
     private static final String TAG = "MdnsResponseDecoder";
     private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
@@ -49,14 +50,8 @@
             List<MdnsResponse> responses, String[] pointer) {
         if (responses != null) {
             for (MdnsResponse response : responses) {
-                List<MdnsPointerRecord> pointerRecords = response.getPointerRecords();
-                if (pointerRecords == null) {
-                    continue;
-                }
-                for (MdnsPointerRecord pointerRecord : pointerRecords) {
-                    if (Arrays.equals(pointerRecord.getPointer(), pointer)) {
-                        return response;
-                    }
+                if (Arrays.equals(response.getServiceName(), pointer)) {
+                    return response;
                 }
             }
         }
@@ -105,7 +100,7 @@
             mdnsPacket = MdnsPacket.parseRecordsSection(reader, flags);
             if (mdnsPacket.answers.size() < 1) {
                 throw new MdnsPacket.ParseException(
-                        MdnsResponseErrorCode.ERROR_NOT_RESPONSE_MESSAGE, "Response has no answers",
+                        MdnsResponseErrorCode.ERROR_NO_ANSWERS, "Response has no answers",
                         null);
             }
             return mdnsPacket;
@@ -116,16 +111,18 @@
     }
 
     /**
-     * Builds mDNS responses for the desired service type from a packet.
+     * Augments a list of {@link MdnsResponse} with records from a packet. The class does not check
+     * the resulting responses for completeness; the caller should do that.
      *
-     * The class does not check the responses for completeness; the caller should do that.
-     *
-     * @param mdnsPacket The packet to read from.
-     * @param interfaceIndex the network interface index (or {@link
-     *     MdnsSocket#INTERFACE_INDEX_UNSPECIFIED} if not known) at which the packet was received.
+     * @param mdnsPacket the response packet with the new records
+     * @param existingResponses list of existing responses. Will not be modified.
+     * @param interfaceIndex the network interface index (or
+     * {@link MdnsSocket#INTERFACE_INDEX_UNSPECIFIED} if not known) at which the packet was received
      * @param network the network at which the packet was received, or null if it is unknown.
+     * @return The set of response instances that were modified or newly added.
      */
-    public List<MdnsResponse> buildResponses(@NonNull MdnsPacket mdnsPacket, int interfaceIndex,
+    public ArraySet<MdnsResponse> augmentResponses(@NonNull MdnsPacket mdnsPacket,
+            @NonNull Collection<MdnsResponse> existingResponses, int interfaceIndex,
             @Nullable Network network) {
         final ArrayList<MdnsRecord> records = new ArrayList<>(
                 mdnsPacket.questions.size() + mdnsPacket.answers.size()
@@ -134,8 +131,11 @@
         records.addAll(mdnsPacket.authorityRecords);
         records.addAll(mdnsPacket.additionalRecords);
 
-        final ArrayList<MdnsResponse> responses = new ArrayList<>();
-
+        final ArraySet<MdnsResponse> modified = new ArraySet<>();
+        final ArrayList<MdnsResponse> responses = new ArrayList<>(existingResponses.size());
+        for (MdnsResponse existing : existingResponses) {
+            responses.add(new MdnsResponse(existing));
+        }
         // The response records are structured in a hierarchy, where some records reference
         // others, as follows:
         //
@@ -175,12 +175,14 @@
                     MdnsResponse response = findResponseWithPointer(responses,
                             pointerRecord.getPointer());
                     if (response == null) {
-                        response = new MdnsResponse(now, interfaceIndex, network);
+                        response = new MdnsResponse(now, pointerRecord.getPointer(), interfaceIndex,
+                                network);
                         responses.add(response);
                     }
-                    // Set interface index earlier because some responses have PTR record only.
-                    // Need to know every response is getting from which interface.
-                    response.addPointerRecord((MdnsPointerRecord) record);
+
+                    if (response.addPointerRecord((MdnsPointerRecord) record)) {
+                        modified.add(response);
+                    }
                 }
             }
         }
@@ -190,14 +192,15 @@
             if (record instanceof MdnsServiceRecord) {
                 MdnsServiceRecord serviceRecord = (MdnsServiceRecord) record;
                 MdnsResponse response = findResponseWithPointer(responses, serviceRecord.getName());
-                if (response != null) {
-                    response.setServiceRecord(serviceRecord);
+                if (response != null && response.setServiceRecord(serviceRecord)) {
+                    response.dropUnmatchedAddressRecords();
+                    modified.add(response);
                 }
             } else if (record instanceof MdnsTextRecord) {
                 MdnsTextRecord textRecord = (MdnsTextRecord) record;
                 MdnsResponse response = findResponseWithPointer(responses, textRecord.getName());
-                if (response != null) {
-                    response.setTextRecord(textRecord);
+                if (response != null && response.setTextRecord(textRecord)) {
+                    modified.add(response);
                 }
             }
         }
@@ -210,26 +213,33 @@
                     List<MdnsResponse> matchingResponses =
                             findResponsesWithHostName(responses, inetRecord.getName());
                     for (MdnsResponse response : matchingResponses) {
-                        assignInetRecord(response, inetRecord);
+                        if (assignInetRecord(response, inetRecord)) {
+                            modified.add(response);
+                        }
                     }
                 } else {
                     MdnsResponse response =
                             findResponseWithHostName(responses, inetRecord.getName());
                     if (response != null) {
-                        assignInetRecord(response, inetRecord);
+                        if (assignInetRecord(response, inetRecord)) {
+                            modified.add(response);
+                        }
                     }
                 }
             }
         }
-        return responses;
+
+        return modified;
     }
 
-    private static void assignInetRecord(MdnsResponse response, MdnsInetAddressRecord inetRecord) {
+    private static boolean assignInetRecord(
+            MdnsResponse response, MdnsInetAddressRecord inetRecord) {
         if (inetRecord.getInet4Address() != null) {
-            response.setInet4AddressRecord(inetRecord);
+            return response.setInet4AddressRecord(inetRecord);
         } else if (inetRecord.getInet6Address() != null) {
-            response.setInet6AddressRecord(inetRecord);
+            return response.setInet6AddressRecord(inetRecord);
         }
+        return false;
     }
 
     private static List<MdnsResponse> findResponsesWithHostName(
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
index 707a57e..f886948 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
@@ -23,6 +23,7 @@
 import android.net.Network;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
@@ -50,6 +51,7 @@
     private static final int DEFAULT_MTU = 1500;
     private static final MdnsLogger LOGGER = new MdnsLogger("MdnsServiceTypeClient");
 
+
     private final String serviceType;
     private final String[] serviceTypeLabels;
     private final MdnsSocketClientBase socketClient;
@@ -216,25 +218,19 @@
      */
     public synchronized void processResponse(@NonNull MdnsPacket packet, int interfaceIndex,
             Network network) {
-        final List<MdnsResponse> responses = responseDecoder.buildResponses(packet, interfaceIndex,
-                network);
-        for (MdnsResponse response : responses) {
-            if (shouldRemoveServiceAfterTtlExpires()) {
-                // Because {@link QueryTask} and {@link processResponse} are running in different
-                // threads. We need to synchronize {@link lock} to protect
-                // {@link instanceNameToResponse} won’t be modified at the same time.
-                synchronized (lock) {
-                    if (response.isGoodbye()) {
-                        onGoodbyeReceived(response.getServiceInstanceName());
-                    } else {
-                        onResponseReceived(response);
-                    }
-                }
-            } else {
-                if (response.isGoodbye()) {
-                    onGoodbyeReceived(response.getServiceInstanceName());
+        synchronized (lock) {
+            // Augment the list of current known responses, and generated responses for resolve
+            // requests if there is no known response
+            final List<MdnsResponse> currentList = new ArrayList<>(instanceNameToResponse.values());
+            currentList.addAll(makeResponsesForResolveIfUnknown(interfaceIndex, network));
+            final ArraySet<MdnsResponse> modifiedResponses = responseDecoder.augmentResponses(
+                    packet, currentList, interfaceIndex, network);
+
+            for (MdnsResponse modified : modifiedResponses) {
+                if (modified.isGoodbye()) {
+                    onGoodbyeReceived(modified.getServiceInstanceName());
                 } else {
-                    onResponseReceived(response);
+                    onResponseModified(modified);
                 }
             }
         }
@@ -246,31 +242,26 @@
         }
     }
 
-    private void onResponseReceived(@NonNull MdnsResponse response) {
-        MdnsResponse currentResponse;
-        currentResponse = instanceNameToResponse.get(response.getServiceInstanceName());
+    private void onResponseModified(@NonNull MdnsResponse response) {
+        final MdnsResponse currentResponse =
+                instanceNameToResponse.get(response.getServiceInstanceName());
 
         boolean newServiceFound = false;
-        boolean existingServiceChanged = false;
         boolean serviceBecomesComplete = false;
         if (currentResponse == null) {
             newServiceFound = true;
-            currentResponse = response;
             String serviceInstanceName = response.getServiceInstanceName();
             if (serviceInstanceName != null) {
-                instanceNameToResponse.put(serviceInstanceName, currentResponse);
+                instanceNameToResponse.put(serviceInstanceName, response);
             }
         } else {
             boolean before = currentResponse.isComplete();
-            existingServiceChanged = currentResponse.mergeRecordsFrom(response);
-            boolean after = currentResponse.isComplete();
+            instanceNameToResponse.put(response.getServiceInstanceName(), response);
+            boolean after = response.isComplete();
             serviceBecomesComplete = !before && after;
         }
-        if (!newServiceFound && !existingServiceChanged) {
-            return;
-        }
         MdnsServiceInfo serviceInfo =
-                buildMdnsServiceInfoFromResponse(currentResponse, serviceTypeLabels);
+                buildMdnsServiceInfoFromResponse(response, serviceTypeLabels);
 
         for (int i = 0; i < listeners.size(); i++) {
             final MdnsServiceBrowserListener listener = listeners.keyAt(i);
@@ -278,7 +269,7 @@
                 listener.onServiceNameDiscovered(serviceInfo);
             }
 
-            if (currentResponse.isComplete()) {
+            if (response.isComplete()) {
                 if (newServiceFound || serviceBecomesComplete) {
                     listener.onServiceFound(serviceInfo);
                 } else {
@@ -413,6 +404,29 @@
         }
     }
 
+    private List<MdnsResponse> makeResponsesForResolveIfUnknown(int interfaceIndex,
+            @NonNull Network network) {
+        final List<MdnsResponse> resolveResponses = new ArrayList<>();
+        for (int i = 0; i < listeners.size(); i++) {
+            final String resolveName = listeners.valueAt(i).getResolveInstanceName();
+            if (resolveName == null) {
+                continue;
+            }
+            MdnsResponse knownResponse = instanceNameToResponse.get(resolveName);
+            if (knownResponse == null) {
+                final ArrayList<String> instanceFullName = new ArrayList<>(
+                        serviceTypeLabels.length + 1);
+                instanceFullName.add(resolveName);
+                instanceFullName.addAll(Arrays.asList(serviceTypeLabels));
+                knownResponse = new MdnsResponse(
+                        0L /* lastUpdateTime */, instanceFullName.toArray(new String[0]),
+                        interfaceIndex, network);
+            }
+            resolveResponses.add(knownResponse);
+        }
+        return resolveResponses;
+    }
+
     // A FutureTask that enqueues a single query, and schedule a new FutureTask for the next task.
     private class QueryTask implements Runnable {
 
@@ -424,35 +438,17 @@
 
         @Override
         public void run() {
-            final List<MdnsResponse> servicesToResolve = new ArrayList<>();
-            boolean sendDiscoveryQueries = false;
+            final List<MdnsResponse> servicesToResolve;
+            final boolean sendDiscoveryQueries;
             synchronized (lock) {
-                for (int i = 0; i < listeners.size(); i++) {
-                    final String resolveName = listeners.valueAt(i).getResolveInstanceName();
-                    if (resolveName == null) {
-                        sendDiscoveryQueries = true;
-                        continue;
-                    }
-                    MdnsResponse knownResponse = instanceNameToResponse.get(resolveName);
-                    if (knownResponse == null) {
-                        // The listener is requesting to resolve a service that has no info in
-                        // cache. Use the provided name to generate a minimal response with just a
-                        // PTR record, so other records are queried to complete it.
-                        // Only the names are used to know which queries to send, other
-                        // parameters do not matter.
-                        knownResponse = new MdnsResponse(
-                                0L /* now */, 0 /* interfaceIndex */, config.network);
-                        final ArrayList<String> instanceFullName = new ArrayList<>(
-                                serviceTypeLabels.length + 1);
-                        instanceFullName.add(resolveName);
-                        instanceFullName.addAll(Arrays.asList(serviceTypeLabels));
-                        knownResponse.addPointerRecord(new MdnsPointerRecord(
-                                serviceTypeLabels, 0L /* receiptTimeMillis */,
-                                false /* cacheFlush */, 0L /* ttlMillis */,
-                                instanceFullName.toArray(new String[0])));
-                    }
-                    servicesToResolve.add(knownResponse);
-                }
+                // The listener is requesting to resolve a service that has no info in
+                // cache. Use the provided name to generate a minimal response, so other records are
+                // queried to complete it.
+                // Only the names are used to know which queries to send, other parameters like
+                // interfaceIndex do not matter.
+                servicesToResolve = makeResponsesForResolveIfUnknown(
+                        0 /* interfaceIndex */, config.network);
+                sendDiscoveryQueries = servicesToResolve.size() < listeners.size();
             }
             Pair<Integer, List<String>> result;
             try {
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 8fc9252..053212b 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -981,7 +981,9 @@
         waitForIdle();
         verify(mSocketProvider).startMonitoringSockets();
         verify(mDiscoveryManager).registerListener(eq(constructedServiceType),
-                listenerCaptor.capture(), argThat(options -> network.equals(options.getNetwork())));
+                listenerCaptor.capture(), argThat(options ->
+                        network.equals(options.getNetwork())
+                                && SERVICE_NAME.equals(options.getResolveInstanceName())));
 
         final MdnsServiceBrowserListener listener = listenerCaptor.getValue();
         final MdnsServiceInfo mdnsServiceInfo = new MdnsServiceInfo(
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
index aaef048..d83c0dd 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
@@ -16,20 +16,26 @@
 
 package com.android.server.connectivity.mdns;
 
+import static android.net.InetAddresses.parseNumericAddress;
+
 import static com.android.server.connectivity.mdns.MdnsResponseDecoder.Clock;
 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.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 
-import android.net.InetAddresses;
 import android.net.Network;
+import android.util.ArraySet;
 
 import com.android.net.module.util.HexDump;
+import com.android.server.connectivity.mdns.MdnsResponseTests.MdnsInet4AddressRecord;
+import com.android.server.connectivity.mdns.MdnsResponseTests.MdnsInet6AddressRecord;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRunner;
 
@@ -43,7 +49,11 @@
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetSocketAddress;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @RunWith(DevSdkIgnoreRunner.class)
 @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
@@ -146,6 +156,44 @@
             + "010001000000780004C0A8018A0000000000000000000000000000"
             + "000000");
 
+    // MDNS record for name "testhost1" with an IPv4 address of 10.1.2.3
+    private static final byte[] DATAIN_IPV4_1 = HexDump.hexStringToByteArray(
+            "0974657374686f73743100000100010000007800040a010203");
+    // MDNS record for name "testhost1" with an IPv4 address of 10.1.2.4
+    private static final byte[] DATAIN_IPV4_2 = HexDump.hexStringToByteArray(
+            "0974657374686f73743100000100010000007800040a010204");
+    // MDNS record w/name "testhost1" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040
+    private static final byte[] DATAIN_IPV6_1 = HexDump.hexStringToByteArray(
+            "0974657374686f73743100001c0001000000780010aabbccdd11223344a0b0c0d010203040");
+    // MDNS record w/name "testhost1" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3030
+    private static final byte[] DATAIN_IPV6_2 = HexDump.hexStringToByteArray(
+            "0974657374686f73743100001c0001000000780010aabbccdd11223344a0b0c0d010203030");
+    // MDNS record w/name "test" & PTR to foo.bar.quxx
+    private static final byte[] DATAIN_PTR_1 = HexDump.hexStringToByteArray(
+            "047465737400000C000100001194000E03666F6F03626172047175787800");
+    // MDNS record w/name "test" & PTR to foo.bar.quxy
+    private static final byte[] DATAIN_PTR_2 = HexDump.hexStringToByteArray(
+            "047465737400000C000100001194000E03666F6F03626172047175787900");
+    // SRV record for: scapy.DNSRRSRV(rrname='foo.bar.quxx', ttl=120, port=1234, target='testhost1')
+    private static final byte[] DATAIN_SERVICE_1 = HexDump.hexStringToByteArray(
+            "03666f6f03626172047175787800002100010000007800110000000004d20974657374686f73743100");
+    // SRV record for: scapy.DNSRRSRV(rrname='foo.bar.quxx', ttl=120, port=1234, target='testhost2')
+    private static final byte[] DATAIN_SERVICE_2 = HexDump.hexStringToByteArray(
+            "03666f6f03626172047175787800002100010000007800110000000004d20974657374686f73743200");
+    // TXT record for: scapy.DNSRR(rrname='foo.bar.quxx', type='TXT', ttl=120,
+    //     rdata=[b'a=hello there', b'b=1234567890', b'xyz=!$$$'])
+    private static final byte[] DATAIN_TEXT_1 = HexDump.hexStringToByteArray(
+            "03666f6f03626172047175787800001000010000007800240d613d68656c6c6f2074686572650c623d3132"
+                    + "33343536373839300878797a3d21242424");
+
+    // TXT record for: scapy.DNSRR(rrname='foo.bar.quxx', type='TXT', ttl=120,
+    //     rdata=[b'a=hello there', b'b=1234567890', b'xyz=!$$$'])
+    private static final byte[] DATAIN_TEXT_2 = HexDump.hexStringToByteArray(
+            "03666f6f03626172047175787800001000010000007800240d613d68656c6c6f2074686572650c623d3132"
+                    + "33343536373839300878797a3d21402324");
+
+    private static final String[] DATAIN_SERVICE_NAME_1 = new String[] { "foo", "bar", "quxx" };
+
     private static final String CAST_SERVICE_NAME = "_googlecast";
     private static final String[] CAST_SERVICE_TYPE =
             new String[] {CAST_SERVICE_NAME, "_tcp", "local"};
@@ -153,7 +201,7 @@
     private static final String[] MATTER_SERVICE_TYPE =
             new String[] {MATTER_SERVICE_NAME, "_tcp", "local"};
 
-    private List<MdnsResponse> responses;
+    private ArraySet<MdnsResponse> responses;
 
     private final Clock mClock = mock(Clock.class);
 
@@ -174,7 +222,7 @@
 
     @Test
     public void testDecodeMultipleAnswerPacket() throws IOException {
-        MdnsResponse response = responses.get(0);
+        MdnsResponse response = responses.valueAt(0);
         assertTrue(response.isComplete());
 
         MdnsInetAddressRecord inet4AddressRecord = response.getInet4AddressRecord();
@@ -224,7 +272,7 @@
 
         responses = decode(decoder, data6);
         assertEquals(1, responses.size());
-        MdnsResponse response = responses.get(0);
+        MdnsResponse response = responses.valueAt(0);
         assertTrue(response.isComplete());
 
         MdnsInetAddressRecord inet6AddressRecord = response.getInet6AddressRecord();
@@ -239,25 +287,30 @@
 
     @Test
     public void testIsComplete() {
-        MdnsResponse response = responses.get(0);
+        MdnsResponse response = new MdnsResponse(responses.valueAt(0));
         assertTrue(response.isComplete());
 
         response.clearPointerRecords();
-        assertFalse(response.isComplete());
+        // The service name is still known in MdnsResponse#getServiceName
+        assertTrue(response.isComplete());
 
-        response = responses.get(0);
+        response = new MdnsResponse(responses.valueAt(0));
         response.setInet4AddressRecord(null);
         assertFalse(response.isComplete());
 
-        response = responses.get(0);
+        response.setInet6AddressRecord(new MdnsInetAddressRecord(new String[] { "testhostname" },
+                0L /* receiptTimeMillis */, false /* cacheFlush */, 1234L /* ttlMillis */,
+                parseNumericAddress("2008:db1::123")));
+        assertTrue(response.isComplete());
+
         response.setInet6AddressRecord(null);
         assertFalse(response.isComplete());
 
-        response = responses.get(0);
+        response = new MdnsResponse(responses.valueAt(0));
         response.setServiceRecord(null);
         assertFalse(response.isComplete());
 
-        response = responses.get(0);
+        response = new MdnsResponse(responses.valueAt(0));
         response.setTextRecord(null);
         assertFalse(response.isComplete());
     }
@@ -274,12 +327,13 @@
         assertNotNull(parsedPacket);
 
         final Network network = mock(Network.class);
-        responses = decoder.buildResponses(parsedPacket,
+        responses = decoder.augmentResponses(parsedPacket,
+                /* existingResponses= */ Collections.emptyList(),
                 /* interfaceIndex= */ 10, network /* expireOnExit= */);
 
         assertEquals(responses.size(), 1);
-        assertEquals(responses.get(0).getInterfaceIndex(), 10);
-        assertEquals(network, responses.get(0).getNetwork());
+        assertEquals(responses.valueAt(0).getInterfaceIndex(), 10);
+        assertEquals(network, responses.valueAt(0).getNetwork());
     }
 
     @Test
@@ -294,17 +348,17 @@
         // This should emit two records:
         assertEquals(2, responses.size());
 
-        MdnsResponse response1 = responses.get(0);
-        MdnsResponse response2 = responses.get(0);
+        MdnsResponse response1 = responses.valueAt(0);
+        MdnsResponse response2 = responses.valueAt(0);
 
         // Both of which are complete:
         assertTrue(response1.isComplete());
         assertTrue(response2.isComplete());
 
         // And should both have the same IPv6 address:
-        assertEquals(InetAddresses.parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
+        assertEquals(parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
                 response1.getInet6AddressRecord().getInet6Address());
-        assertEquals(InetAddresses.parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
+        assertEquals(parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
                 response2.getInet6AddressRecord().getInet6Address());
     }
 
@@ -322,17 +376,206 @@
         assertEquals(2, responses.size());
 
         // But only the first is complete:
-        assertTrue(responses.get(0).isComplete());
-        assertFalse(responses.get(1).isComplete());
+        assertTrue(responses.valueAt(0).isComplete());
+        assertFalse(responses.valueAt(1).isComplete());
+    }
+
+    @Test
+    public void testDecodeWithIpv4AddressChange() throws IOException {
+        MdnsResponse response = makeMdnsResponse(0, DATAIN_SERVICE_NAME_1, List.of(
+                new PacketAndRecordClass(DATAIN_PTR_1,
+                        MdnsPointerRecord.class),
+                new PacketAndRecordClass(DATAIN_SERVICE_1,
+                        MdnsServiceRecord.class),
+                new PacketAndRecordClass(DATAIN_IPV4_1,
+                        MdnsInet4AddressRecord.class)));
+        // Now update the response with another address
+        final MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, null);
+        final ArraySet<MdnsResponse> updatedResponses = decode(
+                decoder, makeResponsePacket(DATAIN_IPV4_2), List.of(response));
+        assertEquals(1, updatedResponses.size());
+        assertEquals(parseNumericAddress("10.1.2.4"),
+                updatedResponses.valueAt(0).getInet4AddressRecord().getInet4Address());
+        assertEquals(parseNumericAddress("10.1.2.3"),
+                response.getInet4AddressRecord().getInet4Address());
+    }
+
+    @Test
+    public void testDecodeWithIpv6AddressChange() throws IOException {
+        MdnsResponse response = makeMdnsResponse(0, DATAIN_SERVICE_NAME_1, List.of(
+                new PacketAndRecordClass(DATAIN_PTR_1,
+                        MdnsPointerRecord.class),
+                new PacketAndRecordClass(DATAIN_SERVICE_1,
+                        MdnsServiceRecord.class),
+                new PacketAndRecordClass(DATAIN_IPV6_1,
+                        MdnsInet6AddressRecord.class)));
+        // Now update the response with another address
+        final MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, null);
+        final ArraySet<MdnsResponse> updatedResponses = decode(
+                decoder, makeResponsePacket(DATAIN_IPV6_2), List.of(response));
+        assertEquals(1, updatedResponses.size());
+        assertEquals(parseNumericAddress("aabb:ccdd:1122:3344:a0b0:c0d0:1020:3030"),
+                updatedResponses.valueAt(0).getInet6AddressRecord().getInet6Address());
+        assertEquals(parseNumericAddress("aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040"),
+                response.getInet6AddressRecord().getInet6Address());
+    }
+
+    @Test
+    public void testDecodeWithChangeOnText() throws IOException {
+        MdnsResponse response = makeMdnsResponse(0, DATAIN_SERVICE_NAME_1, List.of(
+                new PacketAndRecordClass(DATAIN_PTR_1,
+                        MdnsPointerRecord.class),
+                new PacketAndRecordClass(DATAIN_SERVICE_1,
+                        MdnsServiceRecord.class),
+                new PacketAndRecordClass(DATAIN_TEXT_1,
+                        MdnsTextRecord.class)));
+        // Now update the response with another address
+        final MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, null);
+        final ArraySet<MdnsResponse> updatedResponses = decode(
+                decoder, makeResponsePacket(DATAIN_TEXT_2), List.of(response));
+        assertEquals(1, updatedResponses.size());
+        assertEquals(List.of(
+                new MdnsServiceInfo.TextEntry("a", "hello there"),
+                new MdnsServiceInfo.TextEntry("b", "1234567890"),
+                new MdnsServiceInfo.TextEntry("xyz", "!@#$")),
+                updatedResponses.valueAt(0).getTextRecord().getEntries());
+    }
+
+    @Test
+    public void testDecodeWithChangeOnService() throws IOException {
+        MdnsResponse response = makeMdnsResponse(0, DATAIN_SERVICE_NAME_1, List.of(
+                new PacketAndRecordClass(DATAIN_PTR_1,
+                        MdnsPointerRecord.class),
+                new PacketAndRecordClass(DATAIN_SERVICE_1,
+                        MdnsServiceRecord.class),
+                new PacketAndRecordClass(DATAIN_IPV4_1,
+                        MdnsInet4AddressRecord.class)));
+        assertArrayEquals(new String[] { "testhost1" },
+                response.getServiceRecord().getServiceHost());
+        assertNotNull(response.getInet4AddressRecord());
+        // Now update the response with another hostname
+        final MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, null);
+        final ArraySet<MdnsResponse> updatedResponses = decode(
+                decoder, makeResponsePacket(DATAIN_SERVICE_2), List.of(response));
+        assertEquals(1, updatedResponses.size());
+        assertArrayEquals(new String[] { "testhost2" },
+                updatedResponses.valueAt(0).getServiceRecord().getServiceHost());
+        // Hostname changed, so address records are dropped
+        assertNull(updatedResponses.valueAt(0).getInet4AddressRecord());
+    }
+
+    @Test
+    public void testDecodeWithChangeOnPtr() throws IOException {
+        MdnsResponse response = makeMdnsResponse(0, DATAIN_SERVICE_NAME_1, List.of(
+                new PacketAndRecordClass(DATAIN_PTR_1,
+                        MdnsPointerRecord.class),
+                new PacketAndRecordClass(DATAIN_SERVICE_1,
+                        MdnsServiceRecord.class)));
+        // Now update the response with another address
+        final MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, null);
+        final ArraySet<MdnsResponse> updatedResponses = decode(
+                decoder, makeResponsePacket(DATAIN_PTR_2), List.of(response));
+        assertEquals(1, updatedResponses.size());
+        assertArrayEquals(new String[] { "foo", "bar", "quxy" },
+                updatedResponses.valueAt(0).getPointerRecords().get(0).getPointer());
+    }
+
+    @Test
+    public void testDecodeWithNoChange() throws IOException {
+        List<PacketAndRecordClass> recordList =
+                Arrays.asList(
+                        new PacketAndRecordClass(DATAIN_IPV4_1, MdnsInet4AddressRecord.class),
+                        new PacketAndRecordClass(DATAIN_IPV6_1, MdnsInet6AddressRecord.class),
+                        new PacketAndRecordClass(DATAIN_PTR_1, MdnsPointerRecord.class),
+                        new PacketAndRecordClass(DATAIN_SERVICE_2, MdnsServiceRecord.class),
+                        new PacketAndRecordClass(DATAIN_TEXT_1, MdnsTextRecord.class));
+        // Create a two identical responses.
+        MdnsResponse response = makeMdnsResponse(0, DATAIN_SERVICE_NAME_1, recordList);
+
+        final MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, null);
+        final byte[] identicalResponse = makeResponsePacket(
+                recordList.stream().map(p -> p.packetData).collect(Collectors.toList()));
+        final ArraySet<MdnsResponse> changes = decode(
+                decoder, identicalResponse, List.of(response));
+
+        // Decoding should not indicate any change.
+        assertEquals(0, changes.size());
+    }
+
+    private static MdnsResponse makeMdnsResponse(long time, String[] serviceName,
+            List<PacketAndRecordClass> responseList) throws IOException {
+        final MdnsResponse response = new MdnsResponse(
+                time, serviceName, 999 /* interfaceIndex */, mock(Network.class));
+        for (PacketAndRecordClass responseData : responseList) {
+            DatagramPacket packet =
+                    new DatagramPacket(responseData.packetData, responseData.packetData.length);
+            MdnsPacketReader reader = new MdnsPacketReader(packet);
+            String[] name = reader.readLabels();
+            reader.skip(2); // skip record type indication.
+            // Apply the right kind of record to the response.
+            if (responseData.recordClass == MdnsInet4AddressRecord.class) {
+                response.setInet4AddressRecord(new MdnsInet4AddressRecord(name, reader));
+            } else if (responseData.recordClass == MdnsInet6AddressRecord.class) {
+                response.setInet6AddressRecord(new MdnsInet6AddressRecord(name, reader));
+            } else if (responseData.recordClass == MdnsPointerRecord.class) {
+                response.addPointerRecord(new MdnsPointerRecord(name, reader));
+            } else if (responseData.recordClass == MdnsServiceRecord.class) {
+                response.setServiceRecord(new MdnsServiceRecord(name, reader));
+            } else if (responseData.recordClass == MdnsTextRecord.class) {
+                response.setTextRecord(new MdnsTextRecord(name, reader));
+            } else {
+                fail("Unsupported/unexpected MdnsRecord subtype used in test - invalid test!");
+            }
+        }
+        return response;
+    }
+
+    private static byte[] makeResponsePacket(byte[] responseRecord) throws IOException {
+        return makeResponsePacket(List.of(responseRecord));
+    }
+
+    private static byte[] makeResponsePacket(List<byte[]> responseRecords) throws IOException {
+        final MdnsPacketWriter writer = new MdnsPacketWriter(1500);
+        writer.writeUInt16(0); // Transaction ID (advertisement: 0)
+        writer.writeUInt16(0x8400); // Flags: response, authoritative
+        writer.writeUInt16(0); // questions count
+        writer.writeUInt16(responseRecords.size()); // answers count
+        writer.writeUInt16(0); // authority entries count
+        writer.writeUInt16(0); // additional records count
+
+        for (byte[] record : responseRecords) {
+            writer.writeBytes(record);
+        }
+        final DatagramPacket packet = writer.getPacket(new InetSocketAddress(0 /* port */));
+        return Arrays.copyOf(packet.getData(), packet.getLength());
     }
 
 
-    private List<MdnsResponse> decode(MdnsResponseDecoder decoder, byte[] data)
+    // This helper class just wraps the data bytes of a response packet with the contained record
+    // type.
+    // Its only purpose is to make the test code a bit more readable.
+    private static class PacketAndRecordClass {
+        public final byte[] packetData;
+        public final Class<?> recordClass;
+
+        PacketAndRecordClass(byte[] data, Class<?> c) {
+            packetData = data;
+            recordClass = c;
+        }
+    }
+
+    private ArraySet<MdnsResponse> decode(MdnsResponseDecoder decoder, byte[] data)
             throws MdnsPacket.ParseException {
+        return decode(decoder, data, Collections.emptyList());
+    }
+
+    private ArraySet<MdnsResponse> decode(MdnsResponseDecoder decoder, byte[] data,
+            Collection<MdnsResponse> existingResponses) throws MdnsPacket.ParseException {
         final MdnsPacket parsedPacket = MdnsResponseDecoder.parseResponse(data, data.length);
         assertNotNull(parsedPacket);
 
-        return decoder.buildResponses(parsedPacket,
+        return decoder.augmentResponses(parsedPacket,
+                existingResponses,
                 MdnsSocket.INTERFACE_INDEX_UNSPECIFIED, mock(Network.class));
     }
 }
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
index ec57dc8..132a822 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
@@ -16,6 +16,8 @@
 
 package com.android.server.connectivity.mdns;
 
+import static android.net.InetAddresses.parseNumericAddress;
+
 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
 
 import static org.junit.Assert.assertEquals;
@@ -23,22 +25,21 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 
+import static java.util.Collections.emptyList;
+
 import android.net.Network;
 
 import com.android.net.module.util.HexDump;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRunner;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
-import java.util.Arrays;
 import java.util.List;
 
 // The record test data does not use compressed names (label pointers), since that would require
@@ -48,36 +49,24 @@
 public class MdnsResponseTests {
     private static final String TAG = "MdnsResponseTests";
     // MDNS response packet for name "test" with an IPv4 address of 10.1.2.3
-    private static final byte[] dataIn_ipv4_1 = HexDump.hexStringToByteArray(
+    private static final byte[] DATAIN_IPV4 = HexDump.hexStringToByteArray(
             "0474657374000001" + "0001000011940004" + "0A010203");
-    // MDNS response packet for name "tess" with an IPv4 address of 10.1.2.4
-    private static final byte[] dataIn_ipv4_2 = HexDump.hexStringToByteArray(
-            "0474657373000001" + "0001000011940004" + "0A010204");
     // MDNS response w/name "test" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040
-    private static final byte[] dataIn_ipv6_1 = HexDump.hexStringToByteArray(
+    private static final byte[] DATAIN_IPV6 = HexDump.hexStringToByteArray(
             "047465737400001C" + "0001000011940010" + "AABBCCDD11223344" + "A0B0C0D010203040");
-    // MDNS response w/name "test" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3030
-    private static final byte[] dataIn_ipv6_2 = HexDump.hexStringToByteArray(
-            "047465737400001C" + "0001000011940010" + "AABBCCDD11223344" + "A0B0C0D010203030");
     // MDNS response w/name "test" & PTR to foo.bar.quxx
-    private static final byte[] dataIn_ptr_1 = HexDump.hexStringToByteArray(
+    private static final byte[] DATAIN_PTR = HexDump.hexStringToByteArray(
             "047465737400000C" + "000100001194000E" + "03666F6F03626172" + "047175787800");
-    // MDNS response w/name "test" & PTR to foo.bar.quxy
-    private static final byte[] dataIn_ptr_2 = HexDump.hexStringToByteArray(
-            "047465737400000C" + "000100001194000E" + "03666F6F03626172" + "047175787900");
     // MDNS response w/name "test" & Service for host foo.bar.quxx
-    private static final byte[] dataIn_service_1 = HexDump.hexStringToByteArray(
+    private static final byte[] DATAIN_SERVICE = HexDump.hexStringToByteArray(
             "0474657374000021"
             + "0001000011940014"
             + "000100FF1F480366"
             + "6F6F036261720471"
             + "75787800");
-    // MDNS response w/name "test" & Service for host test
-    private static final byte[] dataIn_service_2 = HexDump.hexStringToByteArray(
-            "0474657374000021" + "000100001194000B" + "000100FF1F480474" + "657374");
     // MDNS response w/name "test" & the following text strings:
     // "a=hello there", "b=1234567890", and "xyz=!$$$"
-    private static final byte[] dataIn_text_1 = HexDump.hexStringToByteArray(
+    private static final byte[] DATAIN_TEXT = HexDump.hexStringToByteArray(
             "0474657374000010"
             + "0001000011940024"
             + "0D613D68656C6C6F"
@@ -85,18 +74,11 @@
             + "3D31323334353637"
             + "3839300878797A3D"
             + "21242424");
-    // MDNS response w/name "test" & the following text strings:
-    // "a=hello there", "b=1234567890", and "xyz=!@#$"
-    private static final byte[] dataIn_text_2 = HexDump.hexStringToByteArray(
-            "0474657374000010"
-            + "0001000011940024"
-            + "0D613D68656C6C6F"
-            + "2074686572650C62"
-            + "3D31323334353637"
-            + "3839300878797A3D"
-            + "21402324");
+    private static final String[] TEST_SERVICE_NAME =
+            new String[] { "test", "_type", "_tcp", "local" };
 
     private static final int INTERFACE_INDEX = 999;
+    private static final int TEST_TTL_MS = 120_000;
     private final Network mNetwork = mock(Network.class);
 
     // The following helper classes act as wrappers so that IPv4 and IPv6 address records can
@@ -113,60 +95,36 @@
         }
     }
 
-    // This helper class just wraps the data bytes of a response packet with the contained record
-    // type.
-    // Its only purpose is to make the test code a bit more readable.
-    static class PacketAndRecordClass {
-        public final byte[] packetData;
-        public final Class<?> recordClass;
-
-        public PacketAndRecordClass() {
-            packetData = null;
-            recordClass = null;
-        }
-
-        public PacketAndRecordClass(byte[] data, Class<?> c) {
-            packetData = data;
-            recordClass = c;
-        }
-    }
-
-    // Construct an MdnsResponse with the specified data packets applied.
-    private MdnsResponse makeMdnsResponse(long time, List<PacketAndRecordClass> responseList)
-            throws IOException {
-        MdnsResponse response = new MdnsResponse(time, INTERFACE_INDEX, mNetwork);
-        for (PacketAndRecordClass responseData : responseList) {
-            DatagramPacket packet =
-                    new DatagramPacket(responseData.packetData, responseData.packetData.length);
-            MdnsPacketReader reader = new MdnsPacketReader(packet);
-            String[] name = reader.readLabels();
-            reader.skip(2); // skip record type indication.
-            // Apply the right kind of record to the response.
-            if (responseData.recordClass == MdnsInet4AddressRecord.class) {
-                response.setInet4AddressRecord(new MdnsInet4AddressRecord(name, reader));
-            } else if (responseData.recordClass == MdnsInet6AddressRecord.class) {
-                response.setInet6AddressRecord(new MdnsInet6AddressRecord(name, reader));
-            } else if (responseData.recordClass == MdnsPointerRecord.class) {
-                response.addPointerRecord(new MdnsPointerRecord(name, reader));
-            } else if (responseData.recordClass == MdnsServiceRecord.class) {
-                response.setServiceRecord(new MdnsServiceRecord(name, reader));
-            } else if (responseData.recordClass == MdnsTextRecord.class) {
-                response.setTextRecord(new MdnsTextRecord(name, reader));
-            } else {
-                fail("Unsupported/unexpected MdnsRecord subtype used in test - invalid test!");
-            }
-        }
+    private MdnsResponse makeCompleteResponse(int recordsTtlMillis) {
+        final String[] hostname = new String[] { "MyHostname" };
+        final String[] serviceName = new String[] { "MyService", "_type", "_tcp", "local" };
+        final String[] serviceType = new String[] { "_type", "_tcp", "local" };
+        final MdnsResponse response = new MdnsResponse(/* now= */ 0, serviceName, INTERFACE_INDEX,
+                mNetwork);
+        response.addPointerRecord(new MdnsPointerRecord(serviceType, 0L /* receiptTimeMillis */,
+                false /* cacheFlush */, recordsTtlMillis, serviceName));
+        response.setServiceRecord(new MdnsServiceRecord(serviceName, 0L /* receiptTimeMillis */,
+                true /* cacheFlush */, recordsTtlMillis, 0 /* servicePriority */,
+                0 /* serviceWeight */, 0 /* servicePort */, hostname));
+        response.setTextRecord(new MdnsTextRecord(serviceName, 0L /* receiptTimeMillis */,
+                true /* cacheFlush */, recordsTtlMillis, emptyList() /* entries */));
+        response.setInet4AddressRecord(new MdnsInetAddressRecord(
+                hostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
+                recordsTtlMillis, parseNumericAddress("192.0.2.123")));
+        response.setInet6AddressRecord(new MdnsInetAddressRecord(
+                hostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
+                recordsTtlMillis, parseNumericAddress("2001:db8::123")));
         return response;
     }
 
     @Test
     public void getInet4AddressRecord_returnsAddedRecord() throws IOException {
-        DatagramPacket packet = new DatagramPacket(dataIn_ipv4_1, dataIn_ipv4_1.length);
+        DatagramPacket packet = new DatagramPacket(DATAIN_IPV4, DATAIN_IPV4.length);
         MdnsPacketReader reader = new MdnsPacketReader(packet);
         String[] name = reader.readLabels();
         reader.skip(2); // skip record type indication.
         MdnsInetAddressRecord record = new MdnsInetAddressRecord(name, MdnsRecord.TYPE_A, reader);
-        MdnsResponse response = new MdnsResponse(0, INTERFACE_INDEX, mNetwork);
+        MdnsResponse response = new MdnsResponse(0, TEST_SERVICE_NAME, INTERFACE_INDEX, mNetwork);
         assertFalse(response.hasInet4AddressRecord());
         assertTrue(response.setInet4AddressRecord(record));
         assertEquals(response.getInet4AddressRecord(), record);
@@ -174,13 +132,13 @@
 
     @Test
     public void getInet6AddressRecord_returnsAddedRecord() throws IOException {
-        DatagramPacket packet = new DatagramPacket(dataIn_ipv6_1, dataIn_ipv6_1.length);
+        DatagramPacket packet = new DatagramPacket(DATAIN_IPV6, DATAIN_IPV6.length);
         MdnsPacketReader reader = new MdnsPacketReader(packet);
         String[] name = reader.readLabels();
         reader.skip(2); // skip record type indication.
         MdnsInetAddressRecord record =
                 new MdnsInetAddressRecord(name, MdnsRecord.TYPE_AAAA, reader);
-        MdnsResponse response = new MdnsResponse(0, INTERFACE_INDEX, mNetwork);
+        MdnsResponse response = new MdnsResponse(0, TEST_SERVICE_NAME, INTERFACE_INDEX, mNetwork);
         assertFalse(response.hasInet6AddressRecord());
         assertTrue(response.setInet6AddressRecord(record));
         assertEquals(response.getInet6AddressRecord(), record);
@@ -188,12 +146,12 @@
 
     @Test
     public void getPointerRecords_returnsAddedRecord() throws IOException {
-        DatagramPacket packet = new DatagramPacket(dataIn_ptr_1, dataIn_ptr_1.length);
+        DatagramPacket packet = new DatagramPacket(DATAIN_PTR, DATAIN_PTR.length);
         MdnsPacketReader reader = new MdnsPacketReader(packet);
         String[] name = reader.readLabels();
         reader.skip(2); // skip record type indication.
         MdnsPointerRecord record = new MdnsPointerRecord(name, reader);
-        MdnsResponse response = new MdnsResponse(0, INTERFACE_INDEX, mNetwork);
+        MdnsResponse response = new MdnsResponse(0, record.getPointer(), INTERFACE_INDEX, mNetwork);
         assertFalse(response.hasPointerRecords());
         assertTrue(response.addPointerRecord(record));
         List<MdnsPointerRecord> recordList = response.getPointerRecords();
@@ -204,12 +162,12 @@
 
     @Test
     public void getServiceRecord_returnsAddedRecord() throws IOException {
-        DatagramPacket packet = new DatagramPacket(dataIn_service_1, dataIn_service_1.length);
+        DatagramPacket packet = new DatagramPacket(DATAIN_SERVICE, DATAIN_SERVICE.length);
         MdnsPacketReader reader = new MdnsPacketReader(packet);
         String[] name = reader.readLabels();
         reader.skip(2); // skip record type indication.
         MdnsServiceRecord record = new MdnsServiceRecord(name, reader);
-        MdnsResponse response = new MdnsResponse(0, INTERFACE_INDEX, mNetwork);
+        MdnsResponse response = new MdnsResponse(0, name, INTERFACE_INDEX, mNetwork);
         assertFalse(response.hasServiceRecord());
         assertTrue(response.setServiceRecord(record));
         assertEquals(response.getServiceRecord(), record);
@@ -217,12 +175,12 @@
 
     @Test
     public void getTextRecord_returnsAddedRecord() throws IOException {
-        DatagramPacket packet = new DatagramPacket(dataIn_text_1, dataIn_text_1.length);
+        DatagramPacket packet = new DatagramPacket(DATAIN_TEXT, DATAIN_TEXT.length);
         MdnsPacketReader reader = new MdnsPacketReader(packet);
         String[] name = reader.readLabels();
         reader.skip(2); // skip record type indication.
         MdnsTextRecord record = new MdnsTextRecord(name, reader);
-        MdnsResponse response = new MdnsResponse(0, INTERFACE_INDEX, mNetwork);
+        MdnsResponse response = new MdnsResponse(0, name, INTERFACE_INDEX, mNetwork);
         assertFalse(response.hasTextRecord());
         assertTrue(response.setTextRecord(record));
         assertEquals(response.getTextRecord(), record);
@@ -230,104 +188,84 @@
 
     @Test
     public void getInterfaceIndex() {
-        final MdnsResponse response1 = new MdnsResponse(/* now= */ 0, INTERFACE_INDEX, mNetwork);
+        final MdnsResponse response1 = new MdnsResponse(/* now= */ 0, TEST_SERVICE_NAME,
+                INTERFACE_INDEX, mNetwork);
         assertEquals(INTERFACE_INDEX, response1.getInterfaceIndex());
 
-        final MdnsResponse response2 =
-                new MdnsResponse(/* now= */ 0, 1234 /* interfaceIndex */, mNetwork);
+        final MdnsResponse response2 = new MdnsResponse(/* now= */ 0, TEST_SERVICE_NAME,
+                1234 /* interfaceIndex */, mNetwork);
         assertEquals(1234, response2.getInterfaceIndex());
     }
 
     @Test
     public void testGetNetwork() {
-        final MdnsResponse response1 =
-                new MdnsResponse(/* now= */ 0, INTERFACE_INDEX, null /* network */);
+        final MdnsResponse response1 = new MdnsResponse(/* now= */ 0, TEST_SERVICE_NAME,
+                INTERFACE_INDEX, null /* network */);
         assertNull(response1.getNetwork());
 
-        final MdnsResponse response2 =
-                new MdnsResponse(/* now= */ 0, 1234 /* interfaceIndex */, mNetwork);
+        final MdnsResponse response2 = new MdnsResponse(/* now= */ 0, TEST_SERVICE_NAME,
+                1234 /* interfaceIndex */, mNetwork);
         assertEquals(mNetwork, response2.getNetwork());
     }
 
     @Test
-    public void mergeRecordsFrom_indicates_change_on_ipv4_address() throws IOException {
-        MdnsResponse response = makeMdnsResponse(
-                0,
-                Arrays.asList(
-                        new PacketAndRecordClass(dataIn_ipv4_1, MdnsInet4AddressRecord.class)));
-        // Now create a new response that updates the address.
-        MdnsResponse response2 = makeMdnsResponse(
-                100,
-                Arrays.asList(
-                        new PacketAndRecordClass(dataIn_ipv4_2, MdnsInet4AddressRecord.class)));
-        assertTrue(response.mergeRecordsFrom(response2));
+    public void copyConstructor() {
+        final MdnsResponse response = makeCompleteResponse(TEST_TTL_MS);
+        final MdnsResponse copy = new MdnsResponse(response);
+
+        assertEquals(response.getInet6AddressRecord(), copy.getInet6AddressRecord());
+        assertEquals(response.getInet4AddressRecord(), copy.getInet4AddressRecord());
+        assertEquals(response.getPointerRecords(), copy.getPointerRecords());
+        assertEquals(response.getServiceRecord(), copy.getServiceRecord());
+        assertEquals(response.getTextRecord(), copy.getTextRecord());
+        assertEquals(response.getRecords(), copy.getRecords());
+        assertEquals(response.getNetwork(), copy.getNetwork());
+        assertEquals(response.getInterfaceIndex(), copy.getInterfaceIndex());
     }
 
     @Test
-    public void mergeRecordsFrom_indicates_change_on_ipv6_address() throws IOException {
-        MdnsResponse response = makeMdnsResponse(
-                0,
-                Arrays.asList(
-                        new PacketAndRecordClass(dataIn_ipv6_1, MdnsInet6AddressRecord.class)));
-        // Now create a new response that updates the address.
-        MdnsResponse response2 = makeMdnsResponse(
-                100,
-                Arrays.asList(
-                        new PacketAndRecordClass(dataIn_ipv6_2, MdnsInet6AddressRecord.class)));
-        assertTrue(response.mergeRecordsFrom(response2));
+    public void addRecords_noChange() {
+        final MdnsResponse response = makeCompleteResponse(TEST_TTL_MS);
+
+        assertFalse(response.addPointerRecord(response.getPointerRecords().get(0)));
+        assertFalse(response.setInet6AddressRecord(response.getInet6AddressRecord()));
+        assertFalse(response.setInet4AddressRecord(response.getInet4AddressRecord()));
+        assertFalse(response.setServiceRecord(response.getServiceRecord()));
+        assertFalse(response.setTextRecord(response.getTextRecord()));
     }
 
     @Test
-    public void mergeRecordsFrom_indicates_change_on_text() throws IOException {
-        MdnsResponse response = makeMdnsResponse(
-                0,
-                Arrays.asList(new PacketAndRecordClass(dataIn_text_1, MdnsTextRecord.class)));
-        // Now create a new response that updates the address.
-        MdnsResponse response2 = makeMdnsResponse(
-                100,
-                Arrays.asList(new PacketAndRecordClass(dataIn_text_2, MdnsTextRecord.class)));
-        assertTrue(response.mergeRecordsFrom(response2));
-    }
+    public void addRecords_ttlChange() {
+        final MdnsResponse response = makeCompleteResponse(TEST_TTL_MS);
+        final MdnsResponse ttlZeroResponse = makeCompleteResponse(0);
 
-    @Test
-    public void mergeRecordsFrom_indicates_change_on_service() throws IOException {
-        MdnsResponse response = makeMdnsResponse(
-                0,
-                Arrays.asList(new PacketAndRecordClass(dataIn_service_1, MdnsServiceRecord.class)));
-        // Now create a new response that updates the address.
-        MdnsResponse response2 = makeMdnsResponse(
-                100,
-                Arrays.asList(new PacketAndRecordClass(dataIn_service_2, MdnsServiceRecord.class)));
-        assertTrue(response.mergeRecordsFrom(response2));
-    }
+        assertTrue(response.addPointerRecord(ttlZeroResponse.getPointerRecords().get(0)));
+        assertEquals(1, response.getPointerRecords().size());
+        assertEquals(0, response.getPointerRecords().get(0).getTtl());
+        assertTrue(response.getRecords().stream().anyMatch(r ->
+                r == response.getPointerRecords().get(0)));
 
-    @Test
-    public void mergeRecordsFrom_indicates_change_on_pointer() throws IOException {
-        MdnsResponse response = makeMdnsResponse(
-                0,
-                Arrays.asList(new PacketAndRecordClass(dataIn_ptr_1, MdnsPointerRecord.class)));
-        // Now create a new response that updates the address.
-        MdnsResponse response2 = makeMdnsResponse(
-                100,
-                Arrays.asList(new PacketAndRecordClass(dataIn_ptr_2, MdnsPointerRecord.class)));
-        assertTrue(response.mergeRecordsFrom(response2));
-    }
+        assertTrue(response.setInet6AddressRecord(ttlZeroResponse.getInet6AddressRecord()));
+        assertEquals(0, response.getInet6AddressRecord().getTtl());
+        assertTrue(response.getRecords().stream().anyMatch(r ->
+                r == response.getInet6AddressRecord()));
 
-    @Test
-    @Ignore("MdnsConfigs is not configurable currently.")
-    public void mergeRecordsFrom_indicates_noChange() throws IOException {
-        //MdnsConfigsFlagsImpl.useReducedMergeRecordUpdateEvents.override(true);
-        List<PacketAndRecordClass> recordList =
-                Arrays.asList(
-                        new PacketAndRecordClass(dataIn_ipv4_1, MdnsInet4AddressRecord.class),
-                        new PacketAndRecordClass(dataIn_ipv6_1, MdnsInet6AddressRecord.class),
-                        new PacketAndRecordClass(dataIn_ptr_1, MdnsPointerRecord.class),
-                        new PacketAndRecordClass(dataIn_service_2, MdnsServiceRecord.class),
-                        new PacketAndRecordClass(dataIn_text_1, MdnsTextRecord.class));
-        // Create a two identical responses.
-        MdnsResponse response = makeMdnsResponse(0, recordList);
-        MdnsResponse response2 = makeMdnsResponse(100, recordList);
-        // Merging should not indicate any change.
-        assertFalse(response.mergeRecordsFrom(response2));
+        assertTrue(response.setInet4AddressRecord(ttlZeroResponse.getInet4AddressRecord()));
+        assertEquals(0, response.getInet4AddressRecord().getTtl());
+        assertTrue(response.getRecords().stream().anyMatch(r ->
+                r == response.getInet4AddressRecord()));
+
+        assertTrue(response.setServiceRecord(ttlZeroResponse.getServiceRecord()));
+        assertEquals(0, response.getServiceRecord().getTtl());
+        assertTrue(response.getRecords().stream().anyMatch(r ->
+                r == response.getServiceRecord()));
+
+        assertTrue(response.setTextRecord(ttlZeroResponse.getTextRecord()));
+        assertEquals(0, response.getTextRecord().getTtl());
+        assertTrue(response.getRecords().stream().anyMatch(r ->
+                r == response.getTextRecord()));
+
+        // All records were replaced, not added
+        assertEquals(ttlZeroResponse.getRecords().size(), response.getRecords().size());
     }
 }
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
index d266b3d..a5c6123 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -25,9 +25,11 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -68,6 +70,7 @@
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 
 /** Tests for {@link MdnsServiceTypeClient}. */
 @RunWith(DevSdkIgnoreRunner.class)
@@ -892,6 +895,102 @@
                 mockNetwork);
     }
 
+    @Test
+    public void testProcessResponse_Resolve() throws Exception {
+        client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor);
+
+        final String instanceName = "service-instance";
+        final String[] hostname = new String[] { "testhost "};
+        final String ipV4Address = "192.0.2.0";
+        final String ipV6Address = "2001:db8::";
+
+        final MdnsSearchOptions resolveOptions = MdnsSearchOptions.newBuilder()
+                .setResolveInstanceName(instanceName).build();
+
+        client.startSendAndReceive(mockListenerOne, resolveOptions);
+        InOrder inOrder = inOrder(mockListenerOne, mockSocketClient);
+
+        // Verify a query for SRV/TXT was sent, but no PTR query
+        final ArgumentCaptor<DatagramPacket> srvTxtQueryCaptor =
+                ArgumentCaptor.forClass(DatagramPacket.class);
+        currentThreadExecutor.getAndClearLastScheduledRunnable().run();
+        // Send twice for IPv4 and IPv6
+        inOrder.verify(mockSocketClient, times(2)).sendUnicastPacket(srvTxtQueryCaptor.capture(),
+                eq(null) /* network */);
+
+        final MdnsPacket srvTxtQueryPacket = MdnsPacket.parse(
+                new MdnsPacketReader(srvTxtQueryCaptor.getValue()));
+        final List<MdnsRecord> srvTxtQuestions = srvTxtQueryPacket.questions;
+
+        final String[] serviceName = Stream.concat(Stream.of(instanceName),
+                Arrays.stream(SERVICE_TYPE_LABELS)).toArray(String[]::new);
+        assertFalse(srvTxtQuestions.stream().anyMatch(q -> q.getType() == MdnsRecord.TYPE_PTR));
+        assertTrue(srvTxtQuestions.stream().anyMatch(q ->
+                q.getType() == MdnsRecord.TYPE_SRV && Arrays.equals(q.name, serviceName)));
+        assertTrue(srvTxtQuestions.stream().anyMatch(q ->
+                q.getType() == MdnsRecord.TYPE_TXT && Arrays.equals(q.name, serviceName)));
+
+        // Process a response with SRV+TXT
+        final MdnsPacket srvTxtResponse = new MdnsPacket(
+                0 /* flags */,
+                Collections.emptyList() /* questions */,
+                List.of(
+                        new MdnsServiceRecord(serviceName, 0L /* receiptTimeMillis */,
+                                true /* cacheFlush */, TEST_TTL, 0 /* servicePriority */,
+                                0 /* serviceWeight */, 1234 /* servicePort */, hostname),
+                        new MdnsTextRecord(serviceName, 0L /* receiptTimeMillis */,
+                                true /* cacheFlush */, TEST_TTL,
+                                Collections.emptyList() /* entries */)),
+                Collections.emptyList() /* authorityRecords */,
+                Collections.emptyList() /* additionalRecords */);
+
+        client.processResponse(srvTxtResponse, INTERFACE_INDEX, mockNetwork);
+
+        // Expect a query for A/AAAA
+        final ArgumentCaptor<DatagramPacket> addressQueryCaptor =
+                ArgumentCaptor.forClass(DatagramPacket.class);
+        currentThreadExecutor.getAndClearLastScheduledRunnable().run();
+        inOrder.verify(mockSocketClient, times(2)).sendMulticastPacket(addressQueryCaptor.capture(),
+                eq(null) /* network */);
+
+        final MdnsPacket addressQueryPacket = MdnsPacket.parse(
+                new MdnsPacketReader(addressQueryCaptor.getValue()));
+        final List<MdnsRecord> addressQueryQuestions = addressQueryPacket.questions;
+        assertTrue(addressQueryQuestions.stream().anyMatch(q ->
+                q.getType() == MdnsRecord.TYPE_A && Arrays.equals(q.name, hostname)));
+        assertTrue(addressQueryQuestions.stream().anyMatch(q ->
+                q.getType() == MdnsRecord.TYPE_AAAA && Arrays.equals(q.name, hostname)));
+
+        // Process a response with address records
+        final MdnsPacket addressResponse = new MdnsPacket(
+                0 /* flags */,
+                Collections.emptyList() /* questions */,
+                List.of(
+                        new MdnsInetAddressRecord(hostname, 0L /* receiptTimeMillis */,
+                                true /* cacheFlush */, TEST_TTL,
+                                InetAddresses.parseNumericAddress(ipV4Address)),
+                        new MdnsInetAddressRecord(hostname, 0L /* receiptTimeMillis */,
+                                true /* cacheFlush */, TEST_TTL,
+                                InetAddresses.parseNumericAddress(ipV6Address))),
+                Collections.emptyList() /* authorityRecords */,
+                Collections.emptyList() /* additionalRecords */);
+
+        inOrder.verify(mockListenerOne, never()).onServiceNameDiscovered(any());
+        client.processResponse(addressResponse, INTERFACE_INDEX, mockNetwork);
+
+        inOrder.verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getValue(),
+                instanceName,
+                SERVICE_TYPE_LABELS,
+                ipV4Address,
+                ipV6Address,
+                1234 /* port */,
+                Collections.emptyList() /* subTypes */,
+                Collections.emptyMap() /* attributes */,
+                INTERFACE_INDEX,
+                mockNetwork);
+    }
+
     // verifies that the right query was enqueued with the right delay, and send query by executing
     // the runnable.
     private void verifyAndSendQuery(int index, long timeInMs, boolean expectsUnicastResponse) {
