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

Commit a6d1e12e authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Include Bundle values with ConnectivityDiagnostics calls." am: 797473cc am: 7c0734c9

Change-Id: I5666580210e36ebb87e9e6f467e53086f18fce33
parents f766fbdd 7c0734c9
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);
    }
}