diff --git a/service/Android.bp b/service/Android.bp
index 250693f7f30cb6d344f07c1998826fd9551dfde1..7def20053f3b3d6de0a42f4fdf9048a8a5e61c5c 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -185,7 +185,7 @@ java_library {
         "androidx.annotation_annotation",
         "connectivity-net-module-utils-bpf",
         "connectivity_native_aidl_interface-lateststable-java",
-        "dnsresolver_aidl_interface-V11-java",
+        "dnsresolver_aidl_interface-V12-java",
         "modules-utils-shell-command-handler",
         "net-utils-device-common",
         "net-utils-device-common-ip",
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index dc09237a8e379f57d1e326638e73ec58f25c0b1b..b31b94c5cd4d6cf30ed69f4a220217e12c7e1d67 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -8898,7 +8898,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
         // This network might have been underlying another network. Propagate its capabilities.
         propagateUnderlyingNetworkCapabilities(nai.network);
 
-        if (!newNc.equalsTransportTypes(prevNc)) {
+        if (meteredChanged || !newNc.equalsTransportTypes(prevNc)) {
             mDnsManager.updateCapabilitiesForNetwork(nai.network.getNetId(), newNc);
         }
 
diff --git a/service/src/com/android/server/connectivity/DnsManager.java b/service/src/com/android/server/connectivity/DnsManager.java
index 81b2289ebe41dc70d610250c96e68f7d7c329997..894bcc4793a1819e19a545274a18815217cb722f 100644
--- a/service/src/com/android/server/connectivity/DnsManager.java
+++ b/service/src/com/android/server/connectivity/DnsManager.java
@@ -326,10 +326,14 @@ public class DnsManager {
     }
 
     /**
-     * When creating a new network or transport types are changed in a specific network,
-     * capabilities are always saved to a hashMap before update dns config.
-     * When destroying network, the specific network will be removed from the hashMap.
-     * The hashMap is always accessed on the same thread.
+     * Update {@link NetworkCapabilities} stored in this instance.
+     *
+     * In order to ensure that the resolver has access to necessary information when other events
+     * occur, capabilities are always saved to a hashMap before updating the DNS configuration
+     * whenever a new network is created, transport types are modified, or metered capabilities are
+     * altered for a network. When a network is destroyed, the corresponding entry is removed from
+     * the hashMap. To prevent concurrency issues, the hashMap should always be accessed from the
+     * same thread.
      */
     public void updateCapabilitiesForNetwork(int netId, @NonNull final NetworkCapabilities nc) {
         mNetworkCapabilitiesMap.put(netId, nc);
@@ -385,6 +389,7 @@ public class DnsManager {
                 : useTls ? paramsParcel.servers  // Opportunistic
                 : new String[0];            // Off
         paramsParcel.transportTypes = nc.getTransportTypes();
+        paramsParcel.meteredNetwork = nc.isMetered();
         // Prepare to track the validation status of the DNS servers in the
         // resolver config when private DNS is in opportunistic or strict mode.
         if (useTls) {
@@ -398,12 +403,13 @@ public class DnsManager {
         }
 
         Log.d(TAG, String.format("sendDnsConfigurationForNetwork(%d, %s, %s, %d, %d, %d, %d, "
-                + "%d, %d, %s, %s)", paramsParcel.netId, Arrays.toString(paramsParcel.servers),
-                Arrays.toString(paramsParcel.domains), paramsParcel.sampleValiditySeconds,
-                paramsParcel.successThreshold, paramsParcel.minSamples,
-                paramsParcel.maxSamples, paramsParcel.baseTimeoutMsec,
+                + "%d, %d, %s, %s, %s, %b)", paramsParcel.netId,
+                Arrays.toString(paramsParcel.servers), Arrays.toString(paramsParcel.domains),
+                paramsParcel.sampleValiditySeconds, paramsParcel.successThreshold,
+                paramsParcel.minSamples, paramsParcel.maxSamples, paramsParcel.baseTimeoutMsec,
                 paramsParcel.retryCount, paramsParcel.tlsName,
-                Arrays.toString(paramsParcel.tlsServers)));
+                Arrays.toString(paramsParcel.tlsServers),
+                Arrays.toString(paramsParcel.transportTypes), paramsParcel.meteredNetwork));
 
         try {
             mDnsResolver.setResolverConfiguration(paramsParcel);
diff --git a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
index 9a6fd380245b5958c2aa9c13fa91fa6cf480d79e..545ed16397e3120c48f9daafad046d78fdaaccb7 100644
--- a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
@@ -139,7 +139,8 @@ public class DnsManagerTest {
         assertEquals(actual.tlsConnectTimeoutMs, expected.tlsConnectTimeoutMs);
         assertResolverOptionsEquals(actual.resolverOptions, expected.resolverOptions);
         assertContainsExactly(actual.transportTypes, expected.transportTypes);
-        assertFieldCountEquals(16, ResolverParamsParcel.class);
+        assertEquals(actual.meteredNetwork, expected.meteredNetwork);
+        assertFieldCountEquals(17, ResolverParamsParcel.class);
     }
 
     @Before
@@ -379,6 +380,7 @@ public class DnsManagerTest {
         expectedParams.tlsServers = new String[]{"3.3.3.3", "4.4.4.4"};
         expectedParams.transportTypes = TEST_TRANSPORT_TYPES;
         expectedParams.resolverOptions = null;
+        expectedParams.meteredNetwork = true;
         assertResolverParamsEquals(actualParams, expectedParams);
     }