IpClient: Only use DTIM grace period when SLAAC is used

In IPv6 link-local only mode, the system does not accept RAs, so there
is no reason to lower the DTIM multiplier for IPv6 provisioning.
The same goes for when IPv6 is disabled. And update the integration
tests.

Bug: 266256943
Bug: 280544667
Test: atest NetworkStackIntegrationTests
Change-Id: I4e815981be7f1c6f4581649625162debb603d3d0
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 654c503..75120a9 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -21,6 +21,7 @@
 import static android.net.ip.IIpClient.PROV_IPV4_DISABLED;
 import static android.net.ip.IIpClient.PROV_IPV6_DISABLED;
 import static android.net.ip.IIpClient.PROV_IPV6_LINKLOCAL;
+import static android.net.ip.IIpClient.PROV_IPV6_SLAAC;
 import static android.net.ip.IIpClientCallbacks.DTIM_MULTIPLIER_RESET;
 import static android.net.ip.IpReachabilityMonitor.INVALID_REACHABILITY_LOSS_TYPE;
 import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
@@ -2445,19 +2446,24 @@
         public void enter() {
             mIpProvisioningMetrics.reset();
             mStartTimeMillis = SystemClock.elapsedRealtime();
-            final int delay = mDependencies.getDeviceConfigPropertyInt(
-                    CONFIG_INITIAL_PROVISIONING_DTIM_DELAY_MS,
-                    DEFAULT_INITIAL_PROVISIONING_DTIM_DELAY_MS);
-            mInitialProvisioningEndTimeMillis = mStartTimeMillis + delay;
 
             if (mConfiguration.mProvisioningTimeoutMs > 0) {
                 final long alarmTime = SystemClock.elapsedRealtime()
                         + mConfiguration.mProvisioningTimeoutMs;
                 mProvisioningTimeoutAlarm.schedule(alarmTime);
             }
-            // Send a delay message to wait for IP provisioning to complete eventually and set the
-            // specific DTIM multiplier by checking the target network type.
-            sendMessageDelayed(CMD_SET_DTIM_MULTIPLIER_AFTER_DELAY, delay);
+
+            // There is no need to temporarlily lower the DTIM multiplier in IPv6 link-local
+            // only mode or when IPv6 is disabled.
+            if (mConfiguration.mIPv6ProvisioningMode == PROV_IPV6_SLAAC) {
+                // Send a delay message to wait for IP provisioning to complete eventually and
+                // set the specific DTIM multiplier by checking the target network type.
+                final int delay = mDependencies.getDeviceConfigPropertyInt(
+                        CONFIG_INITIAL_PROVISIONING_DTIM_DELAY_MS,
+                        DEFAULT_INITIAL_PROVISIONING_DTIM_DELAY_MS);
+                mInitialProvisioningEndTimeMillis = mStartTimeMillis + delay;
+                sendMessageDelayed(CMD_SET_DTIM_MULTIPLIER_AFTER_DELAY, delay);
+            }
         }
 
         @Override
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
index 9fee7b5..f6b9783 100644
--- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -4452,23 +4452,25 @@
                 .build();
         startIpClientProvisioning(config);
         verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningSuccess(any());
-        inOrder.verify(mCb).setMaxDtimMultiplier(
+        // IPv6 DTIM grace period doesn't apply to IPv6 link-local only mode and the multiplier
+        // has been initialized to DTIM_MULTIPLIER_RESET before starting provisioning, therefore,
+        // the multiplier should not be updated neither.
+        verify(mCb, never()).setMaxDtimMultiplier(
                 IpClient.DEFAULT_BEFORE_IPV6_PROV_MAX_DTIM_MULTIPLIER);
-        inOrder.verify(mCb, timeout(TEST_TIMEOUT_MS)).setMaxDtimMultiplier(
-                DTIM_MULTIPLIER_RESET);
+        verify(mCb, never()).setMaxDtimMultiplier(DTIM_MULTIPLIER_RESET);
     }
 
     @Test
     public void testMaxDtimMultiplier_IPv4OnlyNetwork() throws Exception {
-        final InOrder inOrder = inOrder(mCb);
         performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S,
                 true /* isDhcpLeaseCacheEnabled */, false /* shouldReplyRapidCommitAck */,
                 TEST_DEFAULT_MTU, false /* isDhcpIpConflictDetectEnabled */);
         verifyIPv4OnlyProvisioningSuccess(Collections.singletonList(CLIENT_ADDR));
-        inOrder.verify(mCb).setMaxDtimMultiplier(
-                IpClient.DEFAULT_BEFORE_IPV6_PROV_MAX_DTIM_MULTIPLIER);
-        inOrder.verify(mCb, timeout(TEST_TIMEOUT_MS)).setMaxDtimMultiplier(
+        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setMaxDtimMultiplier(
                 IpClient.DEFAULT_IPV4_ONLY_NETWORK_MAX_DTIM_MULTIPLIER);
+        // IPv6 DTIM grace period doesn't apply to IPv4-only networks.
+        verify(mCb, never()).setMaxDtimMultiplier(
+                IpClient.DEFAULT_BEFORE_IPV6_PROV_MAX_DTIM_MULTIPLIER);
     }
 
     private void runDualStackNetworkDtimMultiplierSetting(final InOrder inOrder) throws Exception {