Merge "[Thread] fix ServiceDiscoveryTest" into main
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 2f2a342..419ec3a 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -769,7 +769,7 @@
             private Set<String> dedupSubtypeLabels(Collection<String> subtypes) {
                 final Map<String, String> subtypeMap = new LinkedHashMap<>(subtypes.size());
                 for (String subtype : subtypes) {
-                    subtypeMap.put(DnsUtils.toDnsLowerCase(subtype), subtype);
+                    subtypeMap.put(DnsUtils.toDnsUpperCase(subtype), subtype);
                 }
                 return new ArraySet<>(subtypeMap.values());
             }
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 8d85f4e..9c52eca 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
@@ -850,7 +850,7 @@
                 sharedLog.wtf("Invalid priority in config_nsdOffloadServicesPriority: " + entry);
                 continue;
             }
-            priorities.put(DnsUtils.toDnsLowerCase(priorityAndType[1]), priority);
+            priorities.put(DnsUtils.toDnsUpperCase(priorityAndType[1]), priority);
         }
         return priorities;
     }
@@ -996,7 +996,7 @@
             @NonNull Registration registration, byte[] rawOffloadPacket) {
         final NsdServiceInfo nsdServiceInfo = registration.getServiceInfo();
         final Integer mapPriority = mServiceTypeToOffloadPriority.get(
-                DnsUtils.toDnsLowerCase(nsdServiceInfo.getServiceType()));
+                DnsUtils.toDnsUpperCase(nsdServiceInfo.getServiceType()));
         // Higher values of priority are less prioritized
         final int priority = mapPriority == null ? Integer.MAX_VALUE : mapPriority;
         final OffloadServiceInfo offloadServiceInfo = new OffloadServiceInfo(
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
index 170ee9c..8123d27 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
@@ -67,8 +67,8 @@
 
         public void put(@NonNull String serviceType, @NonNull SocketKey socketKey,
                 @NonNull MdnsServiceTypeClient client) {
-            final String dnsLowerServiceType = DnsUtils.toDnsLowerCase(serviceType);
-            final Pair<String, SocketKey> perSocketServiceType = new Pair<>(dnsLowerServiceType,
+            final String dnsUpperServiceType = DnsUtils.toDnsUpperCase(serviceType);
+            final Pair<String, SocketKey> perSocketServiceType = new Pair<>(dnsUpperServiceType,
                     socketKey);
             clients.put(perSocketServiceType, client);
         }
@@ -76,18 +76,18 @@
         @Nullable
         public MdnsServiceTypeClient get(
                 @NonNull String serviceType, @NonNull SocketKey socketKey) {
-            final String dnsLowerServiceType = DnsUtils.toDnsLowerCase(serviceType);
-            final Pair<String, SocketKey> perSocketServiceType = new Pair<>(dnsLowerServiceType,
+            final String dnsUpperServiceType = DnsUtils.toDnsUpperCase(serviceType);
+            final Pair<String, SocketKey> perSocketServiceType = new Pair<>(dnsUpperServiceType,
                     socketKey);
             return clients.getOrDefault(perSocketServiceType, null);
         }
 
         public List<MdnsServiceTypeClient> getByServiceType(@NonNull String serviceType) {
-            final String dnsLowerServiceType = DnsUtils.toDnsLowerCase(serviceType);
+            final String dnsUpperServiceType = DnsUtils.toDnsUpperCase(serviceType);
             final List<MdnsServiceTypeClient> list = new ArrayList<>();
             for (int i = 0; i < clients.size(); i++) {
                 final Pair<String, SocketKey> perSocketServiceType = clients.keyAt(i);
-                if (dnsLowerServiceType.equals(perSocketServiceType.first)) {
+                if (dnsUpperServiceType.equals(perSocketServiceType.first)) {
                     list.add(clients.valueAt(i));
                 }
             }
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsNsecRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsNsecRecord.java
index c168c60..a5b8803 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsNsecRecord.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsNsecRecord.java
@@ -153,7 +153,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(super.hashCode(),
-                Arrays.hashCode(DnsUtils.toDnsLabelsLowerCase(mNextDomain)),
+                Arrays.hashCode(DnsUtils.toDnsLabelsUpperCase(mNextDomain)),
                 Arrays.hashCode(mTypes));
     }
 
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java
index 5619e27..39bf653 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java
@@ -83,7 +83,7 @@
 
     @Override
     public int hashCode() {
-        return (super.hashCode() * 31) + Arrays.hashCode(DnsUtils.toDnsLabelsLowerCase(pointer));
+        return (super.hashCode() * 31) + Arrays.hashCode(DnsUtils.toDnsLabelsUpperCase(pointer));
     }
 
     @Override
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsQueryScheduler.java b/service-t/src/com/android/server/connectivity/mdns/MdnsQueryScheduler.java
index 3fcf0d4..5c02767 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsQueryScheduler.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsQueryScheduler.java
@@ -63,17 +63,22 @@
      * rescheduling is not necessary.
      */
     @Nullable
-    public ScheduledQueryTaskArgs maybeRescheduleCurrentRun(long now,
-            long minRemainingTtl, long lastSentTime, long sessionId) {
+    public ScheduledQueryTaskArgs maybeRescheduleCurrentRun(
+            long now,
+            long minRemainingTtl,
+            long lastSentTime,
+            long sessionId,
+            int numOfQueriesBeforeBackoff) {
         if (mLastScheduledQueryTaskArgs == null) {
             return null;
         }
-        if (!mLastScheduledQueryTaskArgs.config.shouldUseQueryBackoff()) {
+        if (!mLastScheduledQueryTaskArgs.config.shouldUseQueryBackoff(numOfQueriesBeforeBackoff)) {
             return null;
         }
 
         final long timeToRun = calculateTimeToRun(mLastScheduledQueryTaskArgs,
-                mLastScheduledQueryTaskArgs.config, now, minRemainingTtl, lastSentTime);
+                mLastScheduledQueryTaskArgs.config, now, minRemainingTtl, lastSentTime,
+                numOfQueriesBeforeBackoff);
 
         if (timeToRun <= mLastScheduledQueryTaskArgs.timeToRun) {
             return null;
@@ -95,14 +100,16 @@
             long minRemainingTtl,
             long now,
             long lastSentTime,
-            long sessionId) {
-        final QueryTaskConfig nextRunConfig = currentConfig.getConfigForNextRun();
+            long sessionId,
+            int queryMode,
+            int numOfQueriesBeforeBackoff) {
+        final QueryTaskConfig nextRunConfig = currentConfig.getConfigForNextRun(queryMode);
         final long timeToRun;
         if (mLastScheduledQueryTaskArgs == null) {
             timeToRun = now + nextRunConfig.delayUntilNextTaskWithoutBackoffMs;
         } else {
             timeToRun = calculateTimeToRun(mLastScheduledQueryTaskArgs,
-                    nextRunConfig, now, minRemainingTtl, lastSentTime);
+                    nextRunConfig, now, minRemainingTtl, lastSentTime, numOfQueriesBeforeBackoff);
         }
         mLastScheduledQueryTaskArgs = new ScheduledQueryTaskArgs(nextRunConfig, timeToRun,
                 minRemainingTtl + now,
@@ -122,9 +129,10 @@
     }
 
     private static long calculateTimeToRun(@NonNull ScheduledQueryTaskArgs taskArgs,
-            QueryTaskConfig queryTaskConfig, long now, long minRemainingTtl, long lastSentTime) {
+            QueryTaskConfig queryTaskConfig, long now, long minRemainingTtl, long lastSentTime,
+            int numOfQueriesBeforeBackoff) {
         final long baseDelayInMs = queryTaskConfig.delayUntilNextTaskWithoutBackoffMs;
-        if (!queryTaskConfig.shouldUseQueryBackoff()) {
+        if (!queryTaskConfig.shouldUseQueryBackoff(numOfQueriesBeforeBackoff)) {
             return lastSentTime + baseDelayInMs;
         }
         if (minRemainingTtl <= 0) {
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsRecord.java
index 2335459..d464ca7 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsRecord.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsRecord.java
@@ -290,7 +290,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(Arrays.hashCode(DnsUtils.toDnsLabelsLowerCase(name)), type);
+        return Objects.hash(Arrays.hashCode(DnsUtils.toDnsLabelsUpperCase(name)), type);
     }
 
     /**
@@ -311,7 +311,7 @@
 
         public Key(int recordType, String[] recordName) {
             this.recordType = recordType;
-            this.recordName = DnsUtils.toDnsLabelsLowerCase(recordName);
+            this.recordName = DnsUtils.toDnsLabelsUpperCase(recordName);
         }
 
         @Override
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
index 7b304c8..7eea93a 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
@@ -17,7 +17,7 @@
 package com.android.server.connectivity.mdns;
 
 import static com.android.net.module.util.DnsUtils.equalsIgnoreDnsCase;
-import static com.android.net.module.util.DnsUtils.toDnsLowerCase;
+import static com.android.net.module.util.DnsUtils.toDnsUpperCase;
 import static com.android.server.connectivity.mdns.MdnsResponse.EXPIRATION_NEVER;
 import static com.android.server.connectivity.mdns.util.MdnsUtils.ensureRunningOnHandlerThread;
 
@@ -49,16 +49,16 @@
  */
 public class MdnsServiceCache {
     static class CacheKey {
-        @NonNull final String mLowercaseServiceType;
+        @NonNull final String mUpperCaseServiceType;
         @NonNull final SocketKey mSocketKey;
 
         CacheKey(@NonNull String serviceType, @NonNull SocketKey socketKey) {
-            mLowercaseServiceType = toDnsLowerCase(serviceType);
+            mUpperCaseServiceType = toDnsUpperCase(serviceType);
             mSocketKey = socketKey;
         }
 
         @Override public int hashCode() {
-            return Objects.hash(mLowercaseServiceType, mSocketKey);
+            return Objects.hash(mUpperCaseServiceType, mSocketKey);
         }
 
         @Override public boolean equals(Object other) {
@@ -68,7 +68,7 @@
             if (!(other instanceof CacheKey)) {
                 return false;
             }
-            return Objects.equals(mLowercaseServiceType, ((CacheKey) other).mLowercaseServiceType)
+            return Objects.equals(mUpperCaseServiceType, ((CacheKey) other).mUpperCaseServiceType)
                     && Objects.equals(mSocketKey, ((CacheKey) other).mSocketKey);
         }
     }
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java
index 9fa1602..fd716d2 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java
@@ -151,7 +151,7 @@
     public int hashCode() {
         return (super.hashCode() * 31)
                 + Objects.hash(servicePriority, serviceWeight,
-                Arrays.hashCode(DnsUtils.toDnsLabelsLowerCase(serviceHost)),
+                Arrays.hashCode(DnsUtils.toDnsLabelsUpperCase(serviceHost)),
                 servicePort);
     }
 
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 09e5b7f..8959c1b 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
@@ -121,11 +121,11 @@
          * @return true if the service name was not discovered before.
          */
         boolean setServiceDiscovered(@NonNull String serviceName) {
-            return discoveredServiceNames.add(DnsUtils.toDnsLowerCase(serviceName));
+            return discoveredServiceNames.add(DnsUtils.toDnsUpperCase(serviceName));
         }
 
         void unsetServiceDiscovered(@NonNull String serviceName) {
-            discoveredServiceNames.remove(DnsUtils.toDnsLowerCase(serviceName));
+            discoveredServiceNames.remove(DnsUtils.toDnsUpperCase(serviceName));
         }
     }
 
@@ -148,7 +148,8 @@
                     final List<MdnsResponse> servicesToResolve = makeResponsesForResolve(socketKey);
                     final QueryTask queryTask = new QueryTask(taskArgs, servicesToResolve,
                             getAllDiscoverySubtypes(), needSendDiscoveryQueries(listeners),
-                            getExistingServices());
+                            getExistingServices(), searchOptions.onlyUseIpv6OnIpv6OnlyNetworks(),
+                            socketKey);
                     executor.submit(queryTask);
                     break;
                 }
@@ -179,7 +180,9 @@
                                     minRemainingTtl,
                                     now,
                                     lastSentTime,
-                                    sentResult.taskArgs.sessionId
+                                    sentResult.taskArgs.sessionId,
+                                    searchOptions.getQueryMode(),
+                                    searchOptions.numOfQueriesBeforeBackoff()
                             );
                     dependencies.sendMessageDelayed(
                             handler,
@@ -397,10 +400,7 @@
         // Keep tracking the ScheduledFuture for the task so we can cancel it if caller is not
         // interested anymore.
         final QueryTaskConfig taskConfig = new QueryTaskConfig(
-                searchOptions.getQueryMode(),
-                searchOptions.onlyUseIpv6OnIpv6OnlyNetworks(),
-                searchOptions.numOfQueriesBeforeBackoff(),
-                socketKey);
+                searchOptions.getQueryMode());
         final long now = clock.elapsedRealtime();
         if (lastSentTime == 0) {
             lastSentTime = now;
@@ -413,7 +413,9 @@
                             minRemainingTtl,
                             now,
                             lastSentTime,
-                            currentSessionId
+                            currentSessionId,
+                            searchOptions.getQueryMode(),
+                            searchOptions.numOfQueriesBeforeBackoff()
                     );
             dependencies.sendMessageDelayed(
                     handler,
@@ -425,7 +427,8 @@
                     mdnsQueryScheduler.scheduleFirstRun(taskConfig, now,
                             minRemainingTtl, currentSessionId), servicesToResolve,
                     getAllDiscoverySubtypes(), needSendDiscoveryQueries(listeners),
-                    getExistingServices());
+                    getExistingServices(), searchOptions.onlyUseIpv6OnIpv6OnlyNetworks(),
+                    socketKey);
             executor.submit(queryTask);
         }
 
@@ -536,7 +539,8 @@
             final long minRemainingTtl = getMinRemainingTtl(now);
             MdnsQueryScheduler.ScheduledQueryTaskArgs args =
                     mdnsQueryScheduler.maybeRescheduleCurrentRun(now, minRemainingTtl,
-                            lastSentTime, currentSessionId + 1);
+                            lastSentTime, currentSessionId + 1,
+                            searchOptions.numOfQueriesBeforeBackoff());
             if (args != null) {
                 removeScheduledTask();
                 dependencies.sendMessageDelayed(
@@ -724,15 +728,21 @@
         private final List<String> subtypes = new ArrayList<>();
         private final boolean sendDiscoveryQueries;
         private final List<MdnsResponse> existingServices = new ArrayList<>();
+        private final boolean onlyUseIpv6OnIpv6OnlyNetworks;
+        private final SocketKey socketKey;
         QueryTask(@NonNull MdnsQueryScheduler.ScheduledQueryTaskArgs taskArgs,
                 @NonNull Collection<MdnsResponse> servicesToResolve,
                 @NonNull Collection<String> subtypes, boolean sendDiscoveryQueries,
-                @NonNull Collection<MdnsResponse> existingServices) {
+                @NonNull Collection<MdnsResponse> existingServices,
+                boolean onlyUseIpv6OnIpv6OnlyNetworks,
+                @NonNull SocketKey socketKey) {
             this.taskArgs = taskArgs;
             this.servicesToResolve.addAll(servicesToResolve);
             this.subtypes.addAll(subtypes);
             this.sendDiscoveryQueries = sendDiscoveryQueries;
             this.existingServices.addAll(existingServices);
+            this.onlyUseIpv6OnIpv6OnlyNetworks = onlyUseIpv6OnIpv6OnlyNetworks;
+            this.socketKey = socketKey;
         }
 
         @Override
@@ -746,8 +756,8 @@
                                 subtypes,
                                 taskArgs.config.expectUnicastResponse,
                                 taskArgs.config.transactionId,
-                                taskArgs.config.socketKey,
-                                taskArgs.config.onlyUseIpv6OnIpv6OnlyNetworks,
+                                socketKey,
+                                onlyUseIpv6OnIpv6OnlyNetworks,
                                 sendDiscoveryQueries,
                                 servicesToResolve,
                                 clock,
diff --git a/service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java b/service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java
index 0894166..d2cd463 100644
--- a/service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java
+++ b/service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java
@@ -19,9 +19,6 @@
 import static com.android.server.connectivity.mdns.MdnsSearchOptions.AGGRESSIVE_QUERY_MODE;
 import static com.android.server.connectivity.mdns.MdnsSearchOptions.PASSIVE_QUERY_MODE;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
 import com.android.internal.annotations.VisibleForTesting;
 
 /**
@@ -51,9 +48,6 @@
     static final int MAX_TIME_BETWEEN_AGGRESSIVE_BURSTS_MS = 60000;
     private final boolean alwaysAskForUnicastResponse =
             MdnsConfigs.alwaysAskForUnicastResponseInEachBurst();
-    private final int queryMode;
-    final boolean onlyUseIpv6OnIpv6OnlyNetworks;
-    private final int numOfQueriesBeforeBackoff;
     @VisibleForTesting
     final int transactionId;
     @VisibleForTesting
@@ -64,16 +58,11 @@
     final long delayUntilNextTaskWithoutBackoffMs;
     private final boolean isFirstBurst;
     private final long queryCount;
-    @NonNull
-    final SocketKey socketKey;
 
-    QueryTaskConfig(@NonNull QueryTaskConfig other, long queryCount, int transactionId,
+    QueryTaskConfig(long queryCount, int transactionId,
             boolean expectUnicastResponse, boolean isFirstBurst, int burstCounter,
             int queriesPerBurst, int timeBetweenBurstsInMs,
             long delayUntilNextTaskWithoutBackoffMs) {
-        this.queryMode = other.queryMode;
-        this.onlyUseIpv6OnIpv6OnlyNetworks = other.onlyUseIpv6OnIpv6OnlyNetworks;
-        this.numOfQueriesBeforeBackoff = other.numOfQueriesBeforeBackoff;
         this.transactionId = transactionId;
         this.expectUnicastResponse = expectUnicastResponse;
         this.queriesPerBurst = queriesPerBurst;
@@ -82,27 +71,20 @@
         this.delayUntilNextTaskWithoutBackoffMs = delayUntilNextTaskWithoutBackoffMs;
         this.isFirstBurst = isFirstBurst;
         this.queryCount = queryCount;
-        this.socketKey = other.socketKey;
     }
 
-    QueryTaskConfig(int queryMode,
-            boolean onlyUseIpv6OnIpv6OnlyNetworks,
-            int numOfQueriesBeforeBackoff,
-            @Nullable SocketKey socketKey) {
-        this.queryMode = queryMode;
-        this.onlyUseIpv6OnIpv6OnlyNetworks = onlyUseIpv6OnIpv6OnlyNetworks;
-        this.numOfQueriesBeforeBackoff = numOfQueriesBeforeBackoff;
+    QueryTaskConfig(int queryMode) {
         this.queriesPerBurst = QUERIES_PER_BURST;
         this.burstCounter = 0;
         this.transactionId = 1;
         this.expectUnicastResponse = true;
         this.isFirstBurst = true;
         // Config the scan frequency based on the scan mode.
-        if (this.queryMode == AGGRESSIVE_QUERY_MODE) {
+        if (queryMode == AGGRESSIVE_QUERY_MODE) {
             this.timeBetweenBurstsInMs = INITIAL_AGGRESSIVE_TIME_BETWEEN_BURSTS_MS;
             this.delayUntilNextTaskWithoutBackoffMs =
                     TIME_BETWEEN_RETRANSMISSION_QUERIES_IN_BURST_MS;
-        } else if (this.queryMode == PASSIVE_QUERY_MODE) {
+        } else if (queryMode == PASSIVE_QUERY_MODE) {
             // In passive scan mode, sends a single burst of QUERIES_PER_BURST queries, and then
             // in each TIME_BETWEEN_BURSTS interval, sends QUERIES_PER_BURST_PASSIVE_MODE
             // queries.
@@ -116,12 +98,11 @@
             this.timeBetweenBurstsInMs = INITIAL_TIME_BETWEEN_BURSTS_MS;
             this.delayUntilNextTaskWithoutBackoffMs = TIME_BETWEEN_QUERIES_IN_BURST_MS;
         }
-        this.socketKey = socketKey;
         this.queryCount = 0;
     }
 
     long getDelayUntilNextTaskWithoutBackoff(boolean isFirstQueryInBurst,
-            boolean isLastQueryInBurst) {
+            boolean isLastQueryInBurst, int queryMode) {
         if (isFirstQueryInBurst && queryMode == AGGRESSIVE_QUERY_MODE) {
             return 0;
         }
@@ -133,7 +114,7 @@
                 : TIME_BETWEEN_QUERIES_IN_BURST_MS;
     }
 
-    boolean getNextExpectUnicastResponse(boolean isLastQueryInBurst) {
+    boolean getNextExpectUnicastResponse(boolean isLastQueryInBurst, int queryMode) {
         if (!isLastQueryInBurst) {
             return false;
         }
@@ -143,7 +124,7 @@
         return alwaysAskForUnicastResponse;
     }
 
-    int getNextTimeBetweenBurstsMs(boolean isLastQueryInBurst) {
+    int getNextTimeBetweenBurstsMs(boolean isLastQueryInBurst, int queryMode) {
         if (!isLastQueryInBurst) {
             return timeBetweenBurstsInMs;
         }
@@ -155,7 +136,7 @@
     /**
      * Get new QueryTaskConfig for next run.
      */
-    public QueryTaskConfig getConfigForNextRun() {
+    public QueryTaskConfig getConfigForNextRun(int queryMode) {
         long newQueryCount = queryCount + 1;
         int newTransactionId = transactionId + 1;
         if (newTransactionId > UNSIGNED_SHORT_MAX_VALUE) {
@@ -177,16 +158,18 @@
             }
         }
 
-        return new QueryTaskConfig(this, newQueryCount, newTransactionId,
-                getNextExpectUnicastResponse(isLastQueryInBurst), newIsFirstBurst, newBurstCounter,
-                newQueriesPerBurst, getNextTimeBetweenBurstsMs(isLastQueryInBurst),
-                getDelayUntilNextTaskWithoutBackoff(isFirstQueryInBurst, isLastQueryInBurst));
+        return new QueryTaskConfig(newQueryCount, newTransactionId,
+                getNextExpectUnicastResponse(isLastQueryInBurst, queryMode), newIsFirstBurst,
+                newBurstCounter, newQueriesPerBurst,
+                getNextTimeBetweenBurstsMs(isLastQueryInBurst, queryMode),
+                getDelayUntilNextTaskWithoutBackoff(
+                        isFirstQueryInBurst, isLastQueryInBurst, queryMode));
     }
 
     /**
      * Determine if the query backoff should be used.
      */
-    public boolean shouldUseQueryBackoff() {
+    public boolean shouldUseQueryBackoff(int numOfQueriesBeforeBackoff) {
         // Don't enable backoff mode during the burst or in the first burst
         if (burstCounter != 0 || isFirstBurst) {
             return false;
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 4d4dacf..953fd76 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -38,8 +38,8 @@
 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_BACKGROUND;
 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
-import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
 import static android.net.ConnectivityManager.BLOCKED_REASON_NETWORK_RESTRICTED;
+import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
 import static android.net.ConnectivityManager.CALLBACK_AVAILABLE;
 import static android.net.ConnectivityManager.CALLBACK_BLK_CHANGED;
 import static android.net.ConnectivityManager.CALLBACK_CAP_CHANGED;
@@ -56,6 +56,7 @@
 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT;
 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
+import static android.net.ConnectivityManager.NetworkCallback.DECLARED_METHODS_ALL;
 import static android.net.ConnectivityManager.NetworkCallback.DECLARED_METHODS_NONE;
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
@@ -76,7 +77,6 @@
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.getNetworkTypeName;
 import static android.net.ConnectivityManager.isNetworkTypeValid;
-import static android.net.ConnectivityManager.NetworkCallback.DECLARED_METHODS_ALL;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.INetd.PERMISSION_INTERNET;
 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
@@ -145,9 +145,9 @@
 import static com.android.net.module.util.PermissionUtils.hasAnyPermissionOf;
 import static com.android.server.ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE;
 import static com.android.server.connectivity.ConnectivityFlags.DELAY_DESTROY_SOCKETS;
+import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING;
 import static com.android.server.connectivity.ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS;
 import static com.android.server.connectivity.ConnectivityFlags.REQUEST_RESTRICTED_WIFI;
-import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING;
 
 import android.Manifest;
 import android.annotation.CheckResult;
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index c9c8be9..5d6169c 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -58,13 +58,8 @@
         "//apex_available:platform",
     ],
     visibility: [
-        "//frameworks/base/packages/Tethering",
         "//packages/modules/Connectivity:__subpackages__",
         "//packages/modules/Connectivity/framework:__subpackages__",
-        "//frameworks/opt/net/ike",
-        "//frameworks/opt/net/wifi/service",
-        "//packages/modules/Wifi/service",
-        "//frameworks/opt/net/telephony",
         "//packages/modules/NetworkStack:__subpackages__",
         "//packages/modules/CaptivePortalLogin",
     ],
diff --git a/staticlibs/framework/com/android/net/module/util/DnsUtils.java b/staticlibs/framework/com/android/net/module/util/DnsUtils.java
index 2c0dbe6..19ffd72 100644
--- a/staticlibs/framework/com/android/net/module/util/DnsUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/DnsUtils.java
@@ -29,33 +29,33 @@
     private DnsUtils() { }
 
     /**
-     * Convert the string to DNS case-insensitive lowercase
+     * Convert the string to DNS case-insensitive uppercase.
      *
      * Per rfc6762#page-46, accented characters are not defined to be automatically equivalent to
-     * their unaccented counterparts. So the "DNS lowercase" should be if character is A-Z then they
-     * transform into a-z. Otherwise, they are kept as-is.
+     * their unaccented counterparts. So the "DNS uppercase" should be if character is a-z then they
+     * transform into A-Z. Otherwise, they are kept as-is.
      */
-    public static String toDnsLowerCase(@NonNull String string) {
+    public static String toDnsUpperCase(@NonNull String string) {
         final char[] outChars = new char[string.length()];
         for (int i = 0; i < string.length(); i++) {
-            outChars[i] = toDnsLowerCase(string.charAt(i));
+            outChars[i] = toDnsUpperCase(string.charAt(i));
         }
         return new String(outChars);
     }
 
     /**
-     * Convert the array of labels to DNS case-insensitive lowercase.
+     * Convert the array of labels to DNS case-insensitive uppercase.
      */
-    public static String[] toDnsLabelsLowerCase(@NonNull String[] labels) {
+    public static String[] toDnsLabelsUpperCase(@NonNull String[] labels) {
         final String[] outStrings = new String[labels.length];
         for (int i = 0; i < labels.length; ++i) {
-            outStrings[i] = toDnsLowerCase(labels[i]);
+            outStrings[i] = toDnsUpperCase(labels[i]);
         }
         return outStrings;
     }
 
     /**
-     * Compare two strings by DNS case-insensitive lowercase.
+     * Compare two strings by DNS case-insensitive uppercase.
      */
     public static boolean equalsIgnoreDnsCase(@Nullable String a, @Nullable String b) {
         if (a == null || b == null) {
@@ -63,7 +63,7 @@
         }
         if (a.length() != b.length()) return false;
         for (int i = 0; i < a.length(); i++) {
-            if (toDnsLowerCase(a.charAt(i)) != toDnsLowerCase(b.charAt(i))) {
+            if (toDnsUpperCase(a.charAt(i)) != toDnsUpperCase(b.charAt(i))) {
                 return false;
             }
         }
@@ -71,7 +71,7 @@
     }
 
     /**
-     * Compare two set of DNS labels by DNS case-insensitive lowercase.
+     * Compare two set of DNS labels by DNS case-insensitive uppercase.
      */
     public static boolean equalsDnsLabelIgnoreDnsCase(@NonNull String[] a, @NonNull String[] b) {
         if (a == b) {
@@ -89,7 +89,7 @@
         return true;
     }
 
-    private static char toDnsLowerCase(char a) {
-        return a >= 'A' && a <= 'Z' ? (char) (a + ('a' - 'A')) : a;
+    private static char toDnsUpperCase(char a) {
+        return a >= 'a' && a <= 'z' ? (char) (a - ('a' - 'A')) : a;
     }
 }
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/DnsUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/DnsUtilsTest.kt
index 07e1128..7b1f08a 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/DnsUtilsTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/DnsUtilsTest.kt
@@ -18,8 +18,8 @@
 
 import com.android.net.module.util.DnsUtils.equalsDnsLabelIgnoreDnsCase
 import com.android.net.module.util.DnsUtils.equalsIgnoreDnsCase
-import com.android.net.module.util.DnsUtils.toDnsLabelsLowerCase
-import com.android.net.module.util.DnsUtils.toDnsLowerCase
+import com.android.net.module.util.DnsUtils.toDnsLabelsUpperCase
+import com.android.net.module.util.DnsUtils.toDnsUpperCase
 import com.android.testutils.DevSdkIgnoreRunner
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertEquals
@@ -31,23 +31,23 @@
 @RunWith(DevSdkIgnoreRunner::class)
 class DnsUtilsTest {
     @Test
-    fun testToDnsLowerCase() {
-        assertEquals("test", toDnsLowerCase("TEST"))
-        assertEquals("test", toDnsLowerCase("TeSt"))
-        assertEquals("test", toDnsLowerCase("test"))
-        assertEquals("tÉst", toDnsLowerCase("TÉST"))
-        assertEquals("ţést", toDnsLowerCase("ţést"))
+    fun testToDnsUpperCase() {
+        assertEquals("TEST", toDnsUpperCase("TEST"))
+        assertEquals("TEST", toDnsUpperCase("TeSt"))
+        assertEquals("TEST", toDnsUpperCase("test"))
+        assertEquals("TÉST", toDnsUpperCase("TÉST"))
+        assertEquals("ţéST", toDnsUpperCase("ţést"))
         // Unicode characters 0x10000 (𐀀), 0x10001 (𐀁), 0x10041 (𐁁)
         // Note the last 2 bytes of 0x10041 are identical to 'A', but it should remain unchanged.
         assertEquals(
-            "test: -->\ud800\udc00 \ud800\udc01 \ud800\udc41<-- ",
-                toDnsLowerCase("Test: -->\ud800\udc00 \ud800\udc01 \ud800\udc41<-- ")
+            "TEST: -->\ud800\udc00 \ud800\udc01 \ud800\udc41<-- ",
+                toDnsUpperCase("Test: -->\ud800\udc00 \ud800\udc01 \ud800\udc41<-- ")
         )
         // Also test some characters where the first surrogate is not \ud800
         assertEquals(
-            "test: >\ud83c\udff4\udb40\udc67\udb40\udc62\udb40" +
+            "TEST: >\ud83c\udff4\udb40\udc67\udb40\udc62\udb40" +
                 "\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f<",
-                toDnsLowerCase(
+                toDnsUpperCase(
                     "Test: >\ud83c\udff4\udb40\udc67\udb40\udc62\udb40" +
                         "\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f<"
                 )
@@ -55,10 +55,10 @@
     }
 
     @Test
-    fun testToDnsLabelsLowerCase() {
+    fun testToDnsLabelsUpperCase() {
         assertArrayEquals(
-            arrayOf("test", "tÉst", "ţést"),
-            toDnsLabelsLowerCase(arrayOf("TeSt", "TÉST", "ţést"))
+            arrayOf("TEST", "TÉST", "ţéST"),
+            toDnsLabelsUpperCase(arrayOf("TeSt", "TÉST", "ţést"))
         )
     }
 
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 21eb90f..9458460 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -195,7 +195,6 @@
 
 import androidx.test.filters.RequiresDevice;
 import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.DynamicConfigDeviceSide;
 import com.android.internal.util.ArrayUtils;
@@ -211,6 +210,7 @@
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
 import com.android.testutils.DeviceConfigRule;
 import com.android.testutils.DeviceInfoUtils;
 import com.android.testutils.DumpTestUtils;
@@ -274,7 +274,8 @@
 import fi.iki.elonen.NanoHTTPD.Response.IStatus;
 import fi.iki.elonen.NanoHTTPD.Response.Status;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRunner.RestoreDefaultNetwork
 public class ConnectivityManagerTest {
     @Rule(order = 1)
     public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
diff --git a/tests/mts/Android.bp b/tests/mts/Android.bp
index c118d0a..9d158fd 100644
--- a/tests/mts/Android.bp
+++ b/tests/mts/Android.bp
@@ -40,6 +40,6 @@
     srcs: [
         "bpf_existence_test.cpp",
     ],
-    compile_multilib: "first",
+    compile_multilib: "both",
     min_sdk_version: "30", // Ensure test runs on R and above.
 }
diff --git a/tests/native/connectivity_native_test/Android.bp b/tests/native/connectivity_native_test/Android.bp
index c5088c6..ab2f28c 100644
--- a/tests/native/connectivity_native_test/Android.bp
+++ b/tests/native/connectivity_native_test/Android.bp
@@ -32,7 +32,7 @@
         "libmodules-utils-build",
         "libutils",
     ],
-    compile_multilib: "first",
+    compile_multilib: "both",
 }
 
 filegroup {
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 44fa55c..569f4d7 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -562,10 +562,7 @@
         //MdnsConfigsFlagsImpl.alwaysAskForUnicastResponseInEachBurst.override(true);
         MdnsSearchOptions searchOptions = MdnsSearchOptions.newBuilder()
                 .addSubtype(SUBTYPE).setQueryMode(ACTIVE_QUERY_MODE).build();
-        QueryTaskConfig config = new QueryTaskConfig(
-                searchOptions.getQueryMode(),
-                false /* onlyUseIpv6OnIpv6OnlyNetworks */, 3 /* numOfQueriesBeforeBackoff */,
-                socketKey);
+        QueryTaskConfig config = new QueryTaskConfig(searchOptions.getQueryMode());
 
         // This is the first query. We will ask for unicast response.
         assertTrue(config.expectUnicastResponse);
@@ -574,14 +571,14 @@
         // For the rest of queries in this burst, we will NOT ask for unicast response.
         for (int i = 1; i < MdnsConfigs.queriesPerBurst(); i++) {
             int oldTransactionId = config.transactionId;
-            config = config.getConfigForNextRun();
+            config = config.getConfigForNextRun(ACTIVE_QUERY_MODE);
             assertFalse(config.expectUnicastResponse);
             assertEquals(config.transactionId, oldTransactionId + 1);
         }
 
         // This is the first query of a new burst. We will ask for unicast response.
         int oldTransactionId = config.transactionId;
-        config = config.getConfigForNextRun();
+        config = config.getConfigForNextRun(ACTIVE_QUERY_MODE);
         assertTrue(config.expectUnicastResponse);
         assertEquals(config.transactionId, oldTransactionId + 1);
     }
@@ -590,10 +587,7 @@
     public void testQueryTaskConfig_askForUnicastInFirstQuery() {
         MdnsSearchOptions searchOptions = MdnsSearchOptions.newBuilder()
                 .addSubtype(SUBTYPE).setQueryMode(ACTIVE_QUERY_MODE).build();
-        QueryTaskConfig config = new QueryTaskConfig(
-                searchOptions.getQueryMode(),
-                false /* onlyUseIpv6OnIpv6OnlyNetworks */, 3 /* numOfQueriesBeforeBackoff */,
-                socketKey);
+        QueryTaskConfig config = new QueryTaskConfig(searchOptions.getQueryMode());
 
         // This is the first query. We will ask for unicast response.
         assertTrue(config.expectUnicastResponse);
@@ -602,14 +596,14 @@
         // For the rest of queries in this burst, we will NOT ask for unicast response.
         for (int i = 1; i < MdnsConfigs.queriesPerBurst(); i++) {
             int oldTransactionId = config.transactionId;
-            config = config.getConfigForNextRun();
+            config = config.getConfigForNextRun(ACTIVE_QUERY_MODE);
             assertFalse(config.expectUnicastResponse);
             assertEquals(config.transactionId, oldTransactionId + 1);
         }
 
         // This is the first query of a new burst. We will NOT ask for unicast response.
         int oldTransactionId = config.transactionId;
-        config = config.getConfigForNextRun();
+        config = config.getConfigForNextRun(ACTIVE_QUERY_MODE);
         assertFalse(config.expectUnicastResponse);
         assertEquals(config.transactionId, oldTransactionId + 1);
     }