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

Commit 06c353af authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6570253 from 73f220f6 to sc-release

Change-Id: I2ef645a5ab0ef0da19d05d39920c3b0721fc7d00
parents 71bad997 73f220f6
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -25,11 +25,12 @@ import com.android.networkstack.apishim.common.CaptivePortalDataShim;
 * @hide
 */
public class CapportApiProbeResult extends CaptivePortalProbeResult {
    @NonNull
    // CaptivePortalData may be null if the capport API does not send any valid reply.
    @Nullable
    private final CaptivePortalDataShim mCapportData;

    public CapportApiProbeResult(@NonNull CaptivePortalProbeResult result,
            @NonNull CaptivePortalDataShim capportData) {
            @Nullable CaptivePortalDataShim capportData) {
        this(result.mHttpResponseCode, result.redirectUrl, result.detectUrl, capportData,
                result.probeType);
    }
+7 −6
Original line number Diff line number Diff line
@@ -31,11 +31,12 @@ public class DataStallUtils {
    /** Detect data stall using tcp connection fail rate. */
    public static final int DATA_STALL_EVALUATION_TYPE_TCP = 1 << 1;

    @IntDef(prefix = { "DATA_STALL_EVALUATION_TYPE_" }, value = {
    @IntDef(prefix = { "DATA_STALL_EVALUATION_TYPE_" },
        flag = true,
        value = {
            DATA_STALL_EVALUATION_TYPE_NONE,
            DATA_STALL_EVALUATION_TYPE_DNS,
        DATA_STALL_EVALUATION_TYPE_TCP,
    })
            DATA_STALL_EVALUATION_TYPE_TCP, })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EvaluationType {
    }
@@ -96,7 +97,7 @@ public class DataStallUtils {
    /**
     * Default polling interval to observe the tcp health.
     */
    public static int DEFAULT_TCP_POLLING_INTERVAL_MS = 10_000;
    public static int DEFAULT_TCP_POLLING_INTERVAL_MS = 20_000;

    /**
     * Default tcp packets fail rate to suspect as a data stall.
+37 −28
Original line number Diff line number Diff line
@@ -493,7 +493,8 @@ public class NetworkMonitor extends StateMachine {
    @Nullable
    private final DnsStallDetector mDnsStallDetector;
    private long mLastProbeTime;
    // The signal causing a data stall to be suspected. Reset to 0 after metrics are sent to statsd.
    // A bitmask of signals causing a data stall to be suspected. Reset to
    // {@link DataStallUtils#DATA_STALL_EVALUATION_TYPE_NONE} after metrics are sent to statsd.
    private @EvaluationType int mDataStallTypeToCollect;
    private boolean mAcceptPartialConnectivity = false;
    private final EvaluationState mEvaluationState = new EvaluationState();
@@ -2626,7 +2627,7 @@ public class NetworkMonitor extends StateMachine {
                    validationLog("Missing user-portal-url from capport response");
                    return new CapportApiProbeResult(
                            sendDnsAndHttpProbes(mProxy, mUrl, ValidationProbeEvent.PROBE_HTTP),
                            capportData);
                            null /* capportData */);
                }
                final String loginUrlString = capportData.getUserPortalUrl().toString();
                // Starting from R (where CaptivePortalData was introduced), the captive portal app
@@ -3206,7 +3207,8 @@ public class NetworkMonitor extends StateMachine {
            return false;
        }

        Boolean result = null;
        int typeToCollect = 0;
        final int notStall = -1;
        final StringJoiner msg = (DBG || VDBG_STALL) ? new StringJoiner(", ") : null;
        // Reevaluation will generate traffic. Thus, set a minimal reevaluation timer to limit the
        // possible traffic cost in metered network.
@@ -3221,18 +3223,9 @@ public class NetworkMonitor extends StateMachine {
        final TcpSocketTracker tst = getTcpSocketTracker();
        if (dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_TCP) && tst != null) {
            if (tst.getLatestReceivedCount() > 0) {
                result = false;
                typeToCollect = notStall;
            } else if (tst.isDataStallSuspected()) {
                result = true;
                mDataStallTypeToCollect = DATA_STALL_EVALUATION_TYPE_TCP;

                final DataStallReportParcelable p = new DataStallReportParcelable();
                p.detectionMethod = DETECTION_METHOD_TCP_METRICS;
                p.timestampMillis = SystemClock.elapsedRealtime();
                p.tcpPacketFailRate = tst.getLatestPacketFailPercentage();
                p.tcpMetricsCollectionPeriodMillis = getTcpPollingInterval();

                notifyDataStallSuspected(p);
                typeToCollect |= DATA_STALL_EVALUATION_TYPE_TCP;
            }
            if (DBG || VDBG_STALL) {
                msg.add("tcp packets received=" + tst.getLatestReceivedCount())
@@ -3244,32 +3237,48 @@ public class NetworkMonitor extends StateMachine {
        // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold.
        // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms.
        final DnsStallDetector dsd = getDnsStallDetector();
        if ((result == null) && (dsd != null)
        if ((typeToCollect != notStall) && (dsd != null)
                && dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) {
            if (dsd.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold,
                    mDataStallValidDnsTimeThreshold)) {
                result = true;
                mDataStallTypeToCollect = DATA_STALL_EVALUATION_TYPE_DNS;
            if (dsd.isDataStallSuspected(
                    mConsecutiveDnsTimeoutThreshold, mDataStallValidDnsTimeThreshold)) {
                typeToCollect |= DATA_STALL_EVALUATION_TYPE_DNS;
                logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND);
            }
            if (DBG || VDBG_STALL) {
                msg.add("consecutive dns timeout count=" + dsd.getConsecutiveTimeoutCount());
            }
        }

        if (typeToCollect > 0) {
            mDataStallTypeToCollect = typeToCollect;
            final DataStallReportParcelable p = new DataStallReportParcelable();
                p.detectionMethod = DETECTION_METHOD_DNS_EVENTS;
            int detectionMethod = 0;
            p.timestampMillis = SystemClock.elapsedRealtime();
            if (isDataStallTypeDetected(typeToCollect, DATA_STALL_EVALUATION_TYPE_DNS)) {
                detectionMethod |= DETECTION_METHOD_DNS_EVENTS;
                p.dnsConsecutiveTimeouts = mDnsStallDetector.getConsecutiveTimeoutCount();
                notifyDataStallSuspected(p);
            }
            if (DBG || VDBG_STALL) {
                msg.add("consecutive dns timeout count=" + dsd.getConsecutiveTimeoutCount());

            if (isDataStallTypeDetected(typeToCollect, DATA_STALL_EVALUATION_TYPE_TCP)) {
                detectionMethod |= DETECTION_METHOD_TCP_METRICS;
                p.tcpPacketFailRate = tst.getLatestPacketFailPercentage();
                p.tcpMetricsCollectionPeriodMillis = getTcpPollingInterval();
            }
            p.detectionMethod = detectionMethod;
            notifyDataStallSuspected(p);
        }

        // log only data stall suspected.
        if ((DBG && Boolean.TRUE.equals(result)) || VDBG_STALL) {
            log("isDataStall: result=" + result + ", " + msg);
        if ((DBG && (typeToCollect > 0)) || VDBG_STALL) {
            log("isDataStall: result=" + typeToCollect + ", " + msg);
        }

        return (result == null) ? false : result;
        return typeToCollect > 0;
    }

    private static boolean isDataStallTypeDetected(int typeToCollect, int evaluationType) {
        return (typeToCollect & evaluationType) != 0;
    }
    // Class to keep state of evaluation results and probe results.
    //
    // The main purpose was to ensure NetworkMonitor can notify ConnectivityService of probe results
+51 −3
Original line number Diff line number Diff line
@@ -1153,7 +1153,29 @@ public class NetworkMonitorTest {
    }

    @Test
    public void testIsCaptivePortal_CapportApiIsPortal() throws Exception {
    public void testIsCaptivePortal_CapportApiIsPortalWithNullPortalUrl() throws Exception {
        assumeTrue(CaptivePortalDataShimImpl.isSupported());
        setSslException(mHttpsConnection);
        final long bytesRemaining = 10_000L;
        final long secondsRemaining = 500L;
        // Set content without partal url.
        setApiContent(mCapportApiConnection, "{'captive': true,"
                + "'venue-info-url': '" + TEST_VENUE_INFO_URL + "',"
                + "'bytes-remaining': " + bytesRemaining + ","
                + "'seconds-remaining': " + secondsRemaining + "}");
        setPortal302(mHttpConnection);

        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES, VALIDATION_RESULT_PORTAL,
                0 /* probesSucceeded*/, TEST_LOGIN_URL);

        verify(mCapportApiConnection).getResponseCode();

        verify(mHttpConnection, times(1)).getResponseCode();
        verify(mCallbacks, never()).notifyCaptivePortalDataChanged(any());
    }

    @Test
    public void testIsCaptivePortal_CapportApiIsPortalWithValidPortalUrl() throws Exception {
        assumeTrue(CaptivePortalDataShimImpl.isSupported());
        setSslException(mHttpsConnection);
        final long bytesRemaining = 10_000L;
@@ -1596,6 +1618,25 @@ public class NetworkMonitorTest {
        verify(mCallbacks).notifyDataStallSuspected(matchTcpDataStallParcelable());
    }

    @Test
    public void testIsDataStall_EvaluationDnsAndTcp() throws Exception {
        setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS | DATA_STALL_EVALUATION_TYPE_TCP);
        setupTcpDataStall();
        final WrappedNetworkMonitor nm = makeMonitor(CELL_METERED_CAPABILITIES);
        nm.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
        makeDnsTimeoutEvent(nm, DEFAULT_DNS_TIMEOUT_THRESHOLD);
        assertTrue(nm.isDataStall());
        verify(mCallbacks).notifyDataStallSuspected(
                matchDnsAndTcpDataStallParcelable(DEFAULT_DNS_TIMEOUT_THRESHOLD));

        when(mTst.getLatestReceivedCount()).thenReturn(5);
        // Trigger a tcp event immediately.
        setTcpPollingInterval(0);
        nm.sendTcpPollingEvent();
        HandlerUtilsKt.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS);
        assertFalse(nm.isDataStall());
    }

    @Test
    public void testIsDataStall_DisableTcp() {
        // Disable tcp detection with only DNS detect. keep the tcp signal but set to no DNS signal.
@@ -2635,13 +2676,20 @@ public class NetworkMonitorTest {
                && Objects.equals(p.redirectUrl, redirectUrl));
    }

    private DataStallReportParcelable matchDnsAndTcpDataStallParcelable(final int timeoutCount) {
        return argThat(p ->
                (p.detectionMethod & ConstantsShim.DETECTION_METHOD_DNS_EVENTS) != 0
                && (p.detectionMethod & ConstantsShim.DETECTION_METHOD_TCP_METRICS) != 0
                && p.dnsConsecutiveTimeouts == timeoutCount);
    }

    private DataStallReportParcelable matchDnsDataStallParcelable(final int timeoutCount) {
        return argThat(p -> p.detectionMethod == ConstantsShim.DETECTION_METHOD_DNS_EVENTS
        return argThat(p -> (p.detectionMethod & ConstantsShim.DETECTION_METHOD_DNS_EVENTS) != 0
                && p.dnsConsecutiveTimeouts == timeoutCount);
    }

    private DataStallReportParcelable matchTcpDataStallParcelable() {
        return argThat(p -> p.detectionMethod == ConstantsShim.DETECTION_METHOD_TCP_METRICS);
        return argThat(p -> (p.detectionMethod & ConstantsShim.DETECTION_METHOD_TCP_METRICS) != 0);
    }
}