Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 797473cc authored by Cody Kesting's avatar Cody Kesting Committed by Gerrit Code Review
Browse files

Merge "Include Bundle values with ConnectivityDiagnostics calls."

parents 96543546 176bce77
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -20,7 +20,14 @@ package com.android.networkstack.apishim.api29;
 * Utility class for defining and importing constants from the Android platform.
 */
public class ConstantsShim {
    // Constants defined in android.net.ConnectivityDiagnosticsManager.DataStallReport.
    // Constants defined in android.net.ConnectivityDiagnosticsManager.
    public static final int DETECTION_METHOD_DNS_EVENTS = 1;
    public static final int DETECTION_METHOD_TCP_METRICS = 2;
    public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS = "dnsConsecutiveTimeouts";
    public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK = "networkProbesAttemped";
    public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK = "networkProbesSucceeded";
    public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult";
    public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS =
            "tcpMetricsCollectionPeriodMillis";
    public static final String KEY_TCP_PACKET_FAIL_RATE = "tcpPacketFailRate";
}
+12 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.networkstack.apishim;

import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import static android.net.ConnectivityDiagnosticsManager.DataStallReport;

/**
@@ -26,4 +27,15 @@ public class ConstantsShim extends com.android.networkstack.apishim.api29.Consta
            DataStallReport.DETECTION_METHOD_DNS_EVENTS;
    public static final int DETECTION_METHOD_TCP_METRICS =
            DataStallReport.DETECTION_METHOD_TCP_METRICS;
    public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS =
            DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
    public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK =
            ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
    public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK =
            ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
    public static final String KEY_NETWORK_VALIDATION_RESULT =
            ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT;
    public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS =
            DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
    public static final String KEY_TCP_PACKET_FAIL_RATE = DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
}
+28 −7
Original line number Diff line number Diff line
@@ -70,6 +70,12 @@ import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;

import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_DNS_EVENTS;
import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_TCP_METRICS;
import static com.android.networkstack.apishim.ConstantsShim.KEY_DNS_CONSECUTIVE_TIMEOUTS;
import static com.android.networkstack.apishim.ConstantsShim.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
import static com.android.networkstack.apishim.ConstantsShim.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
import static com.android.networkstack.apishim.ConstantsShim.KEY_NETWORK_VALIDATION_RESULT;
import static com.android.networkstack.apishim.ConstantsShim.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
import static com.android.networkstack.apishim.ConstantsShim.KEY_TCP_PACKET_FAIL_RATE;
import static com.android.networkstack.util.DnsUtils.PRIVATE_DNS_PROBE_HOST_SUFFIX;
import static com.android.networkstack.util.DnsUtils.TYPE_ADDRCONFIG;

@@ -584,9 +590,15 @@ public class NetworkMonitor extends StateMachine {
        return NetworkMonitorUtils.isPrivateDnsValidationRequired(mNetworkCapabilities);
    }

    private void notifyNetworkTested(int result, @Nullable String redirectUrl) {
    private void notifyNetworkTested(
            int result, @Nullable String redirectUrl, PersistableBundle extras) {
        try {
            if (mCallbackVersion <= 5) {
                mCallback.notifyNetworkTested(result, redirectUrl);
            } else {
                mCallback.notifyNetworkTestedWithExtras(
                        result, redirectUrl, SystemClock.elapsedRealtime(), extras);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Error sending network test result", e);
        }
@@ -2288,8 +2300,10 @@ public class NetworkMonitor extends StateMachine {
            } else if (tst.isDataStallSuspected()) {
                result = true;

                // TODO(b/147249364): add metrics to PersistableBundle once keys are defined
                notifyDataStallSuspected(DETECTION_METHOD_TCP_METRICS, PersistableBundle.EMPTY);
                final PersistableBundle extras = new PersistableBundle();
                extras.putInt(KEY_TCP_PACKET_FAIL_RATE, tst.getLatestPacketFailPercentage());
                extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, getTcpPollingInterval());
                notifyDataStallSuspected(DETECTION_METHOD_TCP_METRICS, extras);
            }
            if (DBG || VDBG_STALL) {
                msg.add("tcp packets received=" + tst.getLatestReceivedCount())
@@ -2308,8 +2322,10 @@ public class NetworkMonitor extends StateMachine {
                result = true;
                logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND);

                // TODO(b/147249364): add metrics to PersistableBundle once keys are defined
                notifyDataStallSuspected(DETECTION_METHOD_DNS_EVENTS, PersistableBundle.EMPTY);
                final PersistableBundle extras = new PersistableBundle();
                extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS,
                        mDnsStallDetector.getConsecutiveTimeoutCount());
                notifyDataStallSuspected(DETECTION_METHOD_DNS_EVENTS, extras);
            }
            if (DBG || VDBG_STALL) {
                msg.add("consecutive dns timeout count=" + dsd.getConsecutiveTimeoutCount());
@@ -2387,7 +2403,12 @@ public class NetworkMonitor extends StateMachine {
        protected void reportEvaluationResult(int result, @Nullable String redirectUrl) {
            mEvaluationResult = result;
            mRedirectUrl = redirectUrl;
            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
            final PersistableBundle extras = new PersistableBundle();

            extras.putInt(KEY_NETWORK_VALIDATION_RESULT, result);
            extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, mProbeResults);
            extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, mProbeCompleted);
            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl, extras);
        }

        protected int getNetworkTestResult() {
+103 −42
Original line number Diff line number Diff line
@@ -40,6 +40,12 @@ import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;

import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_DNS_EVENTS;
import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_TCP_METRICS;
import static com.android.networkstack.apishim.ConstantsShim.KEY_DNS_CONSECUTIVE_TIMEOUTS;
import static com.android.networkstack.apishim.ConstantsShim.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
import static com.android.networkstack.apishim.ConstantsShim.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
import static com.android.networkstack.apishim.ConstantsShim.KEY_NETWORK_VALIDATION_RESULT;
import static com.android.networkstack.apishim.ConstantsShim.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
import static com.android.networkstack.apishim.ConstantsShim.KEY_TCP_PACKET_FAIL_RATE;
import static com.android.networkstack.util.DnsUtils.PRIVATE_DNS_PROBE_HOST_SUFFIX;

import static junit.framework.Assert.assertEquals;
@@ -51,6 +57,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
@@ -122,6 +129,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -456,10 +464,13 @@ public class NetworkMonitorTest {
    }

    private void resetCallbacks() {
        resetCallbacks(6);
    }

    private void resetCallbacks(int interfaceVersion) {
        reset(mCallbacks);
        // TODO: make this a parameterized test.
        try {
            when(mCallbacks.getInterfaceVersion()).thenReturn(3);
            when(mCallbacks.getInterfaceVersion()).thenReturn(interfaceVersion);
        } catch (RemoteException e) {
            // Can't happen as mCallbacks is a mock
            fail("Error mocking getInterfaceVersion" + e);
@@ -781,7 +792,7 @@ public class NetworkMonitorTest {
        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
        assertTrue(wrappedMonitor.isDataStall());
        verify(mCallbacks).notifyDataStallSuspected(anyLong(), eq(DETECTION_METHOD_DNS_EVENTS),
                any(PersistableBundle.class));
                argThat(getDataStallDnsBundleMatcher()));
    }

    @Test
@@ -794,7 +805,7 @@ public class NetworkMonitorTest {
        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
        assertTrue(wrappedMonitor.isDataStall());
        verify(mCallbacks).notifyDataStallSuspected(anyLong(), eq(DETECTION_METHOD_DNS_EVENTS),
                any(PersistableBundle.class));
                argThat(getDataStallDnsBundleMatcher()));
    }

    @Test
@@ -811,7 +822,7 @@ public class NetworkMonitorTest {
        makeDnsTimeoutEvent(wrappedMonitor, 3);
        assertTrue(wrappedMonitor.isDataStall());
        verify(mCallbacks).notifyDataStallSuspected(anyLong(), eq(DETECTION_METHOD_DNS_EVENTS),
                any(PersistableBundle.class));
                argThat(getDataStallDnsBundleMatcher()));

        // Set the value to larger than the default dns log size.
        setConsecutiveDnsTimeoutThreshold(51);
@@ -823,7 +834,7 @@ public class NetworkMonitorTest {
        makeDnsTimeoutEvent(wrappedMonitor, 1);
        assertTrue(wrappedMonitor.isDataStall());
        verify(mCallbacks, times(2)).notifyDataStallSuspected(anyLong(),
                eq(DETECTION_METHOD_DNS_EVENTS), any(PersistableBundle.class));
                eq(DETECTION_METHOD_DNS_EVENTS), argThat(getDataStallDnsBundleMatcher()));
    }

    @Test
@@ -849,7 +860,7 @@ public class NetworkMonitorTest {
        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
        assertTrue(wrappedMonitor.isDataStall());
        verify(mCallbacks).notifyDataStallSuspected(anyLong(), eq(DETECTION_METHOD_DNS_EVENTS),
                any(PersistableBundle.class));
                argThat(getDataStallDnsBundleMatcher()));

        // Test dns events happened before valid dns time threshold.
        setValidDataStallDnsTimeThreshold(0);
@@ -884,7 +895,7 @@ public class NetworkMonitorTest {
        HandlerUtilsKt.waitForIdle(wrappedMonitor.getHandler(), HANDLER_TIMEOUT_MS);
        assertTrue(wrappedMonitor.isDataStall());
        verify(mCallbacks).notifyDataStallSuspected(anyLong(), eq(DETECTION_METHOD_TCP_METRICS),
                any(PersistableBundle.class));
                argThat(getDataStallTcpBundleMatcher()));
    }

    @Test
@@ -950,8 +961,9 @@ public class NetworkMonitorTest {
        resetCallbacks();
        nm.notifyCaptivePortalAppFinished(APP_RETURN_DISMISSED);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
                .notifyNetworkTested(eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP
                        | NETWORK_VALIDATION_RESULT_VALID), any());
                .notifyNetworkTestedWithExtras(eq(NETWORK_VALIDATION_PROBE_DNS
                        | NETWORK_VALIDATION_PROBE_HTTP | NETWORK_VALIDATION_RESULT_VALID), any(),
                        anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
        assertEquals(0, mRegisteredReceivers.size());
    }

@@ -967,8 +979,9 @@ public class NetworkMonitorTest {
                new InetAddress[0]));
        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
                        eq(null));
                .notifyNetworkTestedWithExtras(eq(VALIDATION_RESULT_VALID
                        | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null), anyLong(),
                        argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(VALIDATION_RESULT_PRIVDNS_VALID));

@@ -978,8 +991,9 @@ public class NetworkMonitorTest {
        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns4.google",
                new InetAddress[0]));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
                        eq(null));
                .notifyNetworkTestedWithExtras(eq(VALIDATION_RESULT_VALID
                        | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null), anyLong(),
                        argThat(getNotifyNetworkTestedBundleMatcher()));
        // NetworkMonitor will check if the probes has changed or not, if the probes has not
        // changed, the callback won't be fired.
        verify(mCallbacks, never()).notifyProbeStatusChanged(
@@ -991,8 +1005,9 @@ public class NetworkMonitorTest {
        mFakeDns.setAnswer("dns.google", new String[]{"192.0.2.3"}, TYPE_A);
        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
                        eq(null));
                .notifyNetworkTestedWithExtras(eq(VALIDATION_RESULT_VALID
                        | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null), anyLong(),
                        argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, never()).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(VALIDATION_RESULT_PRIVDNS_VALID));
    }
@@ -1006,8 +1021,9 @@ public class NetworkMonitorTest {
        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS), eq(null));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTestedWithExtras(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS), eq(null),
                anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS
                | NETWORK_VALIDATION_PROBE_HTTPS));
@@ -1020,8 +1036,9 @@ public class NetworkMonitorTest {
        HandlerUtilsKt.waitForIdle(wnm.getHandler(), HANDLER_TIMEOUT_MS);
        assertEquals(wnm.getEvaluationState().getProbeCompletedResult(), 0);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
                        eq(null));
                .notifyNetworkTestedWithExtras(eq(VALIDATION_RESULT_VALID
                        | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null), anyLong(),
                        argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(VALIDATION_RESULT_PRIVDNS_VALID));
    }
@@ -1035,8 +1052,9 @@ public class NetworkMonitorTest {
        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyNetworkTested(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS), eq(null));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyNetworkTestedWithExtras(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS), eq(null),
                anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS
                | NETWORK_VALIDATION_PROBE_HTTPS));
@@ -1047,8 +1065,9 @@ public class NetworkMonitorTest {

        wnm.forceReevaluation(Process.myUid());
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
                        eq(null));
                .notifyNetworkTestedWithExtras(eq(VALIDATION_RESULT_VALID
                        | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null), anyLong(),
                        argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(VALIDATION_RESULT_PRIVDNS_VALID));

@@ -1060,8 +1079,9 @@ public class NetworkMonitorTest {
        // Strict mode hostname resolve fail. Expect only notification for evaluation fail. No probe
        // notification.
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS))
                .notifyNetworkTested(eq(NETWORK_VALIDATION_PROBE_DNS
                        | NETWORK_VALIDATION_PROBE_HTTPS), eq(null));
                .notifyNetworkTestedWithExtras(eq(NETWORK_VALIDATION_PROBE_DNS
                        | NETWORK_VALIDATION_PROBE_HTTPS), eq(null), anyLong(),
                        argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS
                | NETWORK_VALIDATION_PROBE_HTTPS));
@@ -1072,8 +1092,9 @@ public class NetworkMonitorTest {
        mFakeDns.setNonBypassPrivateDnsWorking(false);
        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google",
                new InetAddress[0]));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyNetworkTested(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS), eq(null));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyNetworkTestedWithExtras(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS), eq(null),
                anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
        // NetworkMonitor will check if the probes has changed or not, if the probes has not
        // changed, the callback won't be fired.
        verify(mCallbacks, never()).notifyProbeStatusChanged(
@@ -1085,8 +1106,9 @@ public class NetworkMonitorTest {
        mFakeDns.setNonBypassPrivateDnsWorking(true);
        wnm.forceReevaluation(Process.myUid());
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
                .notifyNetworkTested(
                        eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null));
                .notifyNetworkTestedWithExtras(
                        eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null),
                        anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
                eq(VALIDATION_RESULT_PRIVDNS_VALID), eq(VALIDATION_RESULT_PRIVDNS_VALID));
    }
@@ -1154,8 +1176,9 @@ public class NetworkMonitorTest {
        resetCallbacks();
        nm.setAcceptPartialConnectivity();
        // Expect to update evaluation result notifications to CS.
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
                eq(VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID), eq(null));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTestedWithExtras(
                eq(VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID), eq(null),
                anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
    }

    @Test
@@ -1230,8 +1253,25 @@ public class NetworkMonitorTest {
        final ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
        // Expect to send HTTP, HTTPs, FALLBACK and evaluation results.
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS))
            .notifyNetworkTested(eq(NETWORK_VALIDATION_PROBE_DNS |
                    NETWORK_VALIDATION_PROBE_FALLBACK | NETWORK_VALIDATION_RESULT_PARTIAL), any());
                .notifyNetworkTestedWithExtras(eq(NETWORK_VALIDATION_PROBE_DNS
                        | NETWORK_VALIDATION_PROBE_FALLBACK | NETWORK_VALIDATION_RESULT_PARTIAL),
                        any(), anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
    }

    @Test
    public void testNotifyNetwork_NotifyNetworkTestedOldInterfaceVersion() throws Exception {
        // Use old interface version so notifyNetworkTested is used over
        // notifyNetworkTestedWithExtras
        resetCallbacks(5);

        // Trigger Network validation
        setStatus(mHttpsConnection, 204);
        setStatus(mHttpConnection, 204);
        final NetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, METERED_CAPABILITIES);

        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS))
                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID), any());
    }

    @Test
@@ -1250,7 +1290,8 @@ public class NetworkMonitorTest {
        resetCallbacks();

        nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.SUCCESS);
        // Verify result should be appended and notifyNetworkTested callback is triggered once.
        // Verify result should be appended and notifyNetworkTestedWithExtras callback is triggered
        // once.
        assertEquals(nm.getEvaluationState().getNetworkTestResult(),
                VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP);

@@ -1266,21 +1307,23 @@ public class NetworkMonitorTest {

        nm.getEvaluationState().reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
                null /* redirectUrl */);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTestedWithExtras(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS
                | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
                | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null), anyLong(),
                argThat(getNotifyNetworkTestedBundleMatcher()));

        nm.getEvaluationState().reportEvaluationResult(
                NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL,
                null /* redirectUrl */);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTestedWithExtras(
                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null),
                anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));

        nm.getEvaluationState().reportEvaluationResult(VALIDATION_RESULT_INVALID,
                TEST_REDIRECT_URL);
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTestedWithExtras(
                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
                eq(TEST_REDIRECT_URL));
                eq(TEST_REDIRECT_URL), anyLong(), argThat(getNotifyNetworkTestedBundleMatcher()));
    }

    private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
@@ -1392,7 +1435,9 @@ public class NetworkMonitorTest {
        monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
        try {
            verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS))
                    .notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture());
                    .notifyNetworkTestedWithExtras(eq(testResult),
                            mNetworkTestedRedirectUrlCaptor.capture(), anyLong(),
                            argThat(getNotifyNetworkTestedBundleMatcher()));
        } catch (RemoteException e) {
            fail("Unexpected exception: " + e);
        }
@@ -1424,5 +1469,21 @@ public class NetworkMonitorTest {
        }
    }

    private ArgumentMatcher<PersistableBundle> getNotifyNetworkTestedBundleMatcher() {
        return bundle ->
                bundle.containsKey(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK)
                && bundle.containsKey(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK)
                && bundle.containsKey(KEY_NETWORK_VALIDATION_RESULT);
    }

    private ArgumentMatcher<PersistableBundle> getDataStallDnsBundleMatcher() {
        return bundle -> bundle.containsKey(KEY_DNS_CONSECUTIVE_TIMEOUTS);
    }

    private ArgumentMatcher<PersistableBundle> getDataStallTcpBundleMatcher() {
        return bundle ->
                bundle.containsKey(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS)
                && bundle.containsKey(KEY_TCP_PACKET_FAIL_RATE);
    }
}