Fix the mStopTimeNs not be reset in Stopwatch#Restart

Bug: 151796056
Test: atest NetworkStackIntegrationTests NetworkStackTests
Test: atest FrameworksNetTests
Test: Manual test with statsd_testdrive
Original-Change: https://android-review.googlesource.com/1343438
Merged-In: Ib83ceb70af3491dacbb4a45f65ef38661ae75e32
Change-Id: Ib83ceb70af3491dacbb4a45f65ef38661ae75e32
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index eeff157..1591f43 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -819,11 +819,11 @@
      * Stop this IpClient.
      *
      * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}.
+     *    The message "arg1" parameter is used to record the disconnect code metrics.
+     *    Usually this method is called by the peer (e.g. wifi) intentionally to stop IpClient,
+     *    consider that's the normal user termination.
      */
     public void stop() {
-        // The message "arg1" parameter is used to record the disconnect code metrics.
-        // Usually this method is called by the peer (e.g. wifi) intentionally to stop IpClient,
-        // consider that's the normal user termination.
         sendMessage(CMD_STOP, DisconnectCode.DC_NORMAL_TERMINATION.getNumber());
     }
 
@@ -1079,8 +1079,6 @@
     }
 
     // Record the DisconnectCode and transition to StoppingState.
-    // When jumping to mStoppingState This function will ensure
-    // that you will not forget to fill in DisconnectCode.
     private void transitionToStoppingState(final DisconnectCode code) {
         mIpProvisioningMetrics.setDisconnectCode(code);
         transitionTo(mStoppingState);
diff --git a/src/android/net/util/Stopwatch.java b/src/android/net/util/Stopwatch.java
index 33653dd..88e523e 100644
--- a/src/android/net/util/Stopwatch.java
+++ b/src/android/net/util/Stopwatch.java
@@ -49,10 +49,11 @@
     }
 
     /**
-     * Retart the Stopwatch.
+     * Restart the Stopwatch.
      */
     public Stopwatch restart() {
         mStartTimeNs = SystemClock.elapsedRealtimeNanos();
+        mStopTimeNs = 0;
         return this;
     }
 
diff --git a/tests/unit/src/com/android/networkstack/metrics/NetworkIpProvisioningMetricsTest.java b/tests/unit/src/com/android/networkstack/metrics/NetworkIpProvisioningMetricsTest.java
index 39906e2..08812b7 100644
--- a/tests/unit/src/com/android/networkstack/metrics/NetworkIpProvisioningMetricsTest.java
+++ b/tests/unit/src/com/android/networkstack/metrics/NetworkIpProvisioningMetricsTest.java
@@ -23,6 +23,7 @@
 import android.stats.connectivity.HostnameTransResult;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -122,6 +123,9 @@
         mMetrics.setDisconnectCode(DisconnectCode.DC_PROVISIONING_TIMEOUT);
         mMetrics.setDisconnectCode(DisconnectCode.DC_ERROR_STARTING_IPV4);
 
+        mMetrics.setIPv4ProvisionedLatencyOnFirstTime(true);
+        mMetrics.setIPv6ProvisionedLatencyOnFirstTime(true);
+
         // Writing the metrics into statsd
         mStats = mMetrics.statsWrite();
 
@@ -133,5 +137,25 @@
         assertEquals(6, mStats.getDhcpSession().getErrorCodeCount());
         assertEquals(HostnameTransResult.HTR_SUCCESS, mStats.getDhcpSession().getHtResult());
         assertEquals(DisconnectCode.DC_PROVISIONING_TIMEOUT, mStats.getDisconnectCode());
+        assertTrue(mStats.getIpv4LatencyMicros() >= 0);
+        assertTrue(mStats.getIpv6LatencyMicros() >= 0);
+        assertTrue(mStats.getProvisioningDurationMicros() >= 0);
+    }
+
+    @Test
+    public void testIpProvisioningMetrics_VerifyConsecutiveMetricsLatency() throws Exception {
+        final IpProvisioningMetrics metrics = new IpProvisioningMetrics();
+        for (int i = 0; i < 2; i++) {
+            metrics.reset();
+            // delay 1 msec.
+            Thread.sleep(1);
+            metrics.setIPv4ProvisionedLatencyOnFirstTime(true);
+            metrics.setIPv6ProvisionedLatencyOnFirstTime(true);
+            NetworkIpProvisioningReported mStats = metrics.statsWrite();
+            // Each timer should be greater than 1000.
+            assertTrue(mStats.getIpv4LatencyMicros() >= 1000);
+            assertTrue(mStats.getIpv6LatencyMicros() >= 1000);
+            assertTrue(mStats.getProvisioningDurationMicros() >= 1000);
+        }
     }
 }