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

Commit 59489e6d authored by Chiachang Wang's avatar Chiachang Wang Committed by Gerrit Code Review
Browse files

Merge "[MP03] Refactor probing class"

parents fd9556e8 717099f5
Loading
Loading
Loading
Loading
+75 −16
Original line number Diff line number Diff line
@@ -16,14 +16,20 @@

package android.net.captiveportal;

import static android.net.metrics.ValidationProbeEvent.PROBE_HTTP;
import static android.net.metrics.ValidationProbeEvent.PROBE_HTTPS;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
 * Result of calling isCaptivePortal().
 * @hide
 */
public final class CaptivePortalProbeResult {
public class CaptivePortalProbeResult {
    public static final int SUCCESS_CODE = 204;
    public static final int FAILED_CODE = 599;
    public static final int PORTAL_CODE = 302;
@@ -42,18 +48,17 @@ public final class CaptivePortalProbeResult {
    // be FAILED if one of the probes returns this status.
    // This logic is only used if the config_force_dns_probe_private_ip_no_internet flag is set.
    public static final int DNS_PRIVATE_IP_RESPONSE_CODE = -2;

    @NonNull
    public static final CaptivePortalProbeResult FAILED = new CaptivePortalProbeResult(FAILED_CODE);
    @NonNull
    public static final CaptivePortalProbeResult SUCCESS =
            new CaptivePortalProbeResult(SUCCESS_CODE);
    public static final CaptivePortalProbeResult PARTIAL =
            new CaptivePortalProbeResult(PARTIAL_CODE);
    // The private IP logic only applies to the HTTP probe.
    public static final CaptivePortalProbeResult PRIVATE_IP =
            new CaptivePortalProbeResult(DNS_PRIVATE_IP_RESPONSE_CODE);
            new CaptivePortalProbeResult(DNS_PRIVATE_IP_RESPONSE_CODE, 1 << PROBE_HTTP);
    // Partial connectivity should be concluded from both HTTP and HTTPS probes.
    @NonNull
    public static final CaptivePortalProbeResult PARTIAL = new CaptivePortalProbeResult(
            PARTIAL_CODE, 1 << PROBE_HTTP | 1 << PROBE_HTTPS);
    // Probe type that is used for unspecified probe result.
    public static final int PROBE_UNKNOWN = 0;

    private final int mHttpResponseCode;  // HTTP response code returned from Internet probe.
    final int mHttpResponseCode;  // HTTP response code returned from Internet probe.
    @Nullable
    public final String redirectUrl;      // Redirect destination returned from Internet probe.
    @Nullable
@@ -62,21 +67,39 @@ public final class CaptivePortalProbeResult {
    @Nullable
    public final CaptivePortalProbeSpec probeSpec;

    public CaptivePortalProbeResult(int httpResponseCode) {
        this(httpResponseCode, null, null);
    // Indicate what kind of probe this is. This is a bitmask constructed by
    // bitwise-or-ing(i.e. {@code |}) the {@code ValidationProbeEvent.PROBE_HTTP} or
    // {@code ValidationProbeEvent.PROBE_HTTPS} values. Set it as {@code PROBE_UNKNOWN} if the probe
    // type is unspecified.
    @ProbeType
    public final int probeType;

    @IntDef(value = {
        PROBE_UNKNOWN,
        1 << PROBE_HTTP,
        1 << PROBE_HTTPS,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ProbeType {
    }

    public CaptivePortalProbeResult(int httpResponseCode, @ProbeType int probeType) {
        this(httpResponseCode, null, null, null, probeType);
    }

    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
            @Nullable String detectUrl) {
        this(httpResponseCode, redirectUrl, detectUrl, null);
            @Nullable String detectUrl, @ProbeType int probeType) {
        this(httpResponseCode, redirectUrl, detectUrl, null, probeType);
    }

    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
            @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec) {
            @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec,
            @ProbeType int probeType) {
        mHttpResponseCode = httpResponseCode;
        this.redirectUrl = redirectUrl;
        this.detectUrl = detectUrl;
        this.probeSpec = probeSpec;
        this.probeType = probeType;
    }

    public boolean isSuccessful() {
@@ -98,4 +121,40 @@ public final class CaptivePortalProbeResult {
    public boolean isDnsPrivateIpResponse() {
        return mHttpResponseCode == DNS_PRIVATE_IP_RESPONSE_CODE;
    }

    /**
     *  Make a failed {@code this} for either HTTPS or HTTP determined by {@param isHttps}.
     *  @param probeType probe type of the result.
     *  @return a failed {@link CaptivePortalProbeResult}
     */
    public static CaptivePortalProbeResult failed(@ProbeType int probeType) {
        return new CaptivePortalProbeResult(FAILED_CODE, probeType);
    }

    /**
     *  Make a success {@code this} for either HTTPS or HTTP determined by {@param isHttps}.
     *  @param probeType probe type of the result.
     *  @return a success {@link CaptivePortalProbeResult}
     */
    public static CaptivePortalProbeResult success(@ProbeType int probeType) {
        return new CaptivePortalProbeResult(SUCCESS_CODE, probeType);
    }

    /**
     * As {@code this} is the result of calling isCaptivePortal(), the result may be determined from
     * one or more probes depending on the configuration of detection probes. Return if HTTPS probe
     * is one of the probes that concludes it.
     */
    public boolean isConcludedFromHttps() {
        return (probeType & (1 << PROBE_HTTPS)) != 0;
    }

    /**
     * As {@code this} is the result of calling isCaptivePortal(), the result may be determined from
     * one or more probes depending on the configuration of detection probes. Return if HTTP probe
     * is one of the probes that concludes it.
     */
    public boolean isConcludedFromHttp() {
        return (probeType & (1 << PROBE_HTTP)) != 0;
    }
}
+15 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.net.captiveportal;

import static android.net.captiveportal.CaptivePortalProbeResult.PORTAL_CODE;
import static android.net.captiveportal.CaptivePortalProbeResult.SUCCESS_CODE;
import static android.net.metrics.ValidationProbeEvent.PROBE_HTTP;

import android.text.TextUtils;
import android.util.Log;
@@ -40,6 +41,7 @@ public abstract class CaptivePortalProbeSpec {
    private static final String TAG = CaptivePortalProbeSpec.class.getSimpleName();
    private static final String REGEX_SEPARATOR = "@@/@@";
    private static final String SPEC_SEPARATOR = "@@,@@";
    private static final String PROTOCOL_HTTP = "http";

    private final String mEncodedSpec;
    private final URL mUrl;
@@ -138,7 +140,7 @@ public abstract class CaptivePortalProbeSpec {
    }

    /**
     * Get the probe result from HTTP status and location header.
     * Get the HTTP probe result from HTTP status and location header.
     */
    @NonNull
    public abstract CaptivePortalProbeResult getResult(int status, @Nullable String locationHeader);
@@ -157,6 +159,7 @@ public abstract class CaptivePortalProbeSpec {
     * Implementation of {@link CaptivePortalProbeSpec} that is based on configurable regular
     * expressions for the HTTP status code and location header (if any). Matches indicate that
     * the page is not a portal.
     * @throws IllegalArgumentException The protocol of the url is not http.
     * This probe cannot fail: it always returns SUCCESS_CODE or PORTAL_CODE
     */
    private static class RegexMatchProbeSpec extends CaptivePortalProbeSpec {
@@ -165,9 +168,17 @@ public abstract class CaptivePortalProbeSpec {
        @Nullable
        final Pattern mLocationHeaderRegex;

        RegexMatchProbeSpec(
                String spec, URL url, Pattern statusRegex, Pattern locationHeaderRegex) {
        RegexMatchProbeSpec(@NonNull String spec, @NonNull URL url, @Nullable Pattern statusRegex,
                @Nullable Pattern locationHeaderRegex) throws ParseException {
            super(spec, url);
            final String protocol = url.getProtocol();
            if (!PROTOCOL_HTTP.equals(protocol)) {
                // The probe type taken in the result is hard-coded as PROBE_HTTP currently, so the
                // probe type taken into the result of {@code getResult} have to change if other
                // kind of probes are used.
                throw new IllegalArgumentException("Protocol for probe spec should be http but was"
                        + protocol);
            }
            mStatusRegex = statusRegex;
            mLocationHeaderRegex = locationHeaderRegex;
        }
@@ -178,7 +189,7 @@ public abstract class CaptivePortalProbeSpec {
            final boolean locationMatch = safeMatch(locationHeader, mLocationHeaderRegex);
            final int returnCode = statusMatch && locationMatch ? SUCCESS_CODE : PORTAL_CODE;
            return new CaptivePortalProbeResult(
                    returnCode, locationHeader, getUrl().toString(), this);
                    returnCode, locationHeader, getUrl().toString(), this, PROBE_HTTP);
        }
    }

+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.net.captiveportal;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.networkstack.apishim.CaptivePortalDataShim;

/**
 * Captive portal probe detection result including capport API detection result.
 * @hide
 */
public class CapportApiProbeResult extends CaptivePortalProbeResult {
    @NonNull
    private final CaptivePortalDataShim mCapportData;

    public CapportApiProbeResult(@NonNull CaptivePortalProbeResult result,
            @NonNull CaptivePortalDataShim capportData) {
        this(result.mHttpResponseCode, result.redirectUrl, result.detectUrl, capportData,
                result.probeType);
    }

    public CapportApiProbeResult(int httpResponseCode, @Nullable String redirectUrl,
            @Nullable String detectUrl, @Nullable CaptivePortalDataShim capportData,
            int probeType) {
        super(httpResponseCode, redirectUrl, detectUrl, probeType);
        mCapportData = capportData;
    }

    public CaptivePortalDataShim getCaptivePortalData() {
        return mCapportData;
    }
}
+90 −67
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ import android.net.NetworkCapabilities;
import android.net.ProxyInfo;
import android.net.TrafficStats;
import android.net.Uri;
import android.net.captiveportal.CapportApiProbeResult;
import android.net.captiveportal.CaptivePortalProbeResult;
import android.net.captiveportal.CaptivePortalProbeSpec;
import android.net.metrics.IpConnectivityLog;
@@ -406,7 +407,8 @@ public class NetworkMonitor extends StateMachine {
    private final Stopwatch mEvaluationTimer = new Stopwatch();

    // This variable is set before transitioning to the mCaptivePortalState.
    private CaptivePortalProbeResult mLastPortalProbeResult = CaptivePortalProbeResult.FAILED;
    private CaptivePortalProbeResult mLastPortalProbeResult =
            CaptivePortalProbeResult.failed(CaptivePortalProbeResult.PROBE_UNKNOWN);

    // Random generator to select fallback URL index
    private final Random mRandom;
@@ -1840,7 +1842,7 @@ public class NetworkMonitor extends StateMachine {
    protected CaptivePortalProbeResult isCaptivePortal() {
        if (!mIsCaptivePortalCheckEnabled) {
            validationLog("Validation disabled.");
            return CaptivePortalProbeResult.SUCCESS;
            return CaptivePortalProbeResult.success(CaptivePortalProbeResult.PROBE_UNKNOWN);
        }

        URL pacUrl = null;
@@ -1868,13 +1870,13 @@ public class NetworkMonitor extends StateMachine {
        if (proxyInfo != null && !Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) {
            pacUrl = makeURL(proxyInfo.getPacFileUrl().toString());
            if (pacUrl == null) {
                return CaptivePortalProbeResult.FAILED;
                return CaptivePortalProbeResult.failed(CaptivePortalProbeResult.PROBE_UNKNOWN);
            }
        }

        if ((pacUrl == null) && (httpUrls.length == 0 || httpsUrls.length == 0
                || httpUrls[0] == null || httpsUrls[0] == null)) {
            return CaptivePortalProbeResult.FAILED;
            return CaptivePortalProbeResult.failed(CaptivePortalProbeResult.PROBE_UNKNOWN);
        }

        long startTime = SystemClock.elapsedRealtime();
@@ -2073,7 +2075,8 @@ public class NetworkMonitor extends StateMachine {
        logValidationProbe(probeTimer.stop(), probeType, httpResponseCode);

        if (probeSpec == null) {
            return new CaptivePortalProbeResult(httpResponseCode, redirectUrl, url.toString());
            return new CaptivePortalProbeResult(httpResponseCode, redirectUrl, url.toString(),
                    1 << probeType);
        } else {
            return probeSpec.getResult(httpResponseCode, redirectUrl);
        }
@@ -2162,33 +2165,29 @@ public class NetworkMonitor extends StateMachine {
        }
    }

    private abstract static class ProbeThread extends Thread {
    private class ProbeThread extends Thread {
        private final CountDownLatch mLatch;
        private final ProxyInfo mProxy;
        private final URL mUrl;
        protected final Uri mCaptivePortalApiUrl;
        private final Probe mProbe;

        protected ProbeThread(CountDownLatch latch, ProxyInfo proxy, URL url,
        ProbeThread(CountDownLatch latch, ProxyInfo proxy, URL url, int probeType,
                Uri captivePortalApiUrl) {
            mLatch = latch;
            mProxy = proxy;
            mUrl = url;
            mCaptivePortalApiUrl = captivePortalApiUrl;
            mProbe = (probeType == ValidationProbeEvent.PROBE_HTTPS)
                    ? new HttpsProbe(proxy, url, captivePortalApiUrl)
                    : new HttpProbe(proxy, url, captivePortalApiUrl);
            mResult = CaptivePortalProbeResult.failed(probeType);
        }

        private volatile CaptivePortalProbeResult mResult = CaptivePortalProbeResult.FAILED;
        private volatile CaptivePortalProbeResult mResult;

        public CaptivePortalProbeResult result() {
            return mResult;
        }

        protected abstract CaptivePortalProbeResult sendProbe(ProxyInfo proxy, URL url);
        public abstract boolean isConclusiveResult(CaptivePortalProbeResult result);

        @Override
        public void run() {
            mResult = sendProbe(mProxy, mUrl);
            if (isConclusiveResult(mResult)) {
            mResult = mProbe.sendProbe();
            if (isConclusiveResult(mResult, mProbe.mCaptivePortalApiUrl)) {
                // Stop waiting immediately if any probe is conclusive.
                while (mLatch.getCount() > 0) {
                    mLatch.countDown();
@@ -2199,36 +2198,34 @@ public class NetworkMonitor extends StateMachine {
        }
    }

    final class HttpsProbeThread extends ProbeThread {
        HttpsProbeThread(CountDownLatch latch, ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
            super(latch, proxy, url, captivePortalApiUrl);
    private abstract static class Probe {
        protected final ProxyInfo mProxy;
        protected final URL mUrl;
        protected final Uri mCaptivePortalApiUrl;

        protected Probe(ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
            mProxy = proxy;
            mUrl = url;
            mCaptivePortalApiUrl = captivePortalApiUrl;
        }
        // sendProbe() is synchronous and blocks until it has the result.
        protected abstract CaptivePortalProbeResult sendProbe();
    }

        @Override
        protected CaptivePortalProbeResult sendProbe(ProxyInfo proxy, URL url) {
            return sendDnsAndHttpProbes(proxy, url, ValidationProbeEvent.PROBE_HTTPS);
    final class HttpsProbe extends Probe {
        HttpsProbe(ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
            super(proxy, url, captivePortalApiUrl);
        }

        @Override
        public boolean isConclusiveResult(CaptivePortalProbeResult result) {
            // isPortal() is not expected on the HTTPS probe, but check it nonetheless.
            // In case the capport API is available, the API is authoritative on whether there is
            // a portal, so the HTTPS probe is not enough to conclude there is connectivity,
            // and a determination will be made once the capport API probe returns. Note that the
            // API can only force the system to detect a portal even if the HTTPS probe succeeds.
            // It cannot force the system to detect no portal if the HTTPS probe fails.
            return (result.isPortal() || result.isSuccessful()) && mCaptivePortalApiUrl == null;
        }
        protected CaptivePortalProbeResult sendProbe() {
            return sendDnsAndHttpProbes(mProxy, mUrl, ValidationProbeEvent.PROBE_HTTPS);
        }

    final class HttpProbeThread extends ProbeThread {
        private volatile CaptivePortalDataShim mCapportData;
        HttpProbeThread(CountDownLatch latch, ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
            super(latch, proxy, url, captivePortalApiUrl);
    }

        CaptivePortalDataShim getCaptivePortalData() {
            return mCapportData;
    final class HttpProbe extends Probe {
        HttpProbe(ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
            super(proxy, url, captivePortalApiUrl);
        }

        private CaptivePortalDataShim tryCapportApiProbe() {
@@ -2277,33 +2274,61 @@ public class NetworkMonitor extends StateMachine {
        }

        @Override
        protected CaptivePortalProbeResult sendProbe(ProxyInfo proxy, URL url) {
            mCapportData = tryCapportApiProbe();
            if (mCapportData != null && mCapportData.isCaptive()) {
                if (mCapportData.getUserPortalUrl() == null) {
        protected CaptivePortalProbeResult sendProbe() {
            final CaptivePortalDataShim capportData = tryCapportApiProbe();
            if (capportData != null && capportData.isCaptive()) {
                if (capportData.getUserPortalUrl() == null) {
                    validationLog("Missing user-portal-url from capport response");
                    return sendDnsAndHttpProbes(proxy, url, ValidationProbeEvent.PROBE_HTTP);
                    return sendDnsAndHttpProbes(mProxy, mUrl, ValidationProbeEvent.PROBE_HTTP);
                }
                final String loginUrlString = mCapportData.getUserPortalUrl().toString();
                final String loginUrlString = capportData.getUserPortalUrl().toString();
                // Starting from R (where CaptivePortalData was introduced), the captive portal app
                // delegates to NetworkMonitor for verifying when the network validates instead of
                // probing the detectUrl. So pass the detectUrl to have the portal open on that,
                // page; CaptivePortalLogin will not use it for probing.
                return new CaptivePortalProbeResult(
                return new CapportApiProbeResult(
                        CaptivePortalProbeResult.PORTAL_CODE,
                        loginUrlString /* redirectUrl */,
                        loginUrlString /* detectUrl */);
                        loginUrlString /* detectUrl */,
                        capportData,
                        1 << ValidationProbeEvent.PROBE_HTTP);
            }

            // If the API says it's not captive, still check for HTTP connectivity. This helps
            // with partial connectivity detection, and a broken API saying that there is no
            // redirect when there is one.
            return sendDnsAndHttpProbes(proxy, url, ValidationProbeEvent.PROBE_HTTP);
            final CaptivePortalProbeResult res =
                    sendDnsAndHttpProbes(mProxy, mUrl, ValidationProbeEvent.PROBE_HTTP);
            return capportData == null ? res : new CapportApiProbeResult(res, capportData);
        }
    }

        @Override
        public boolean isConclusiveResult(CaptivePortalProbeResult result) {
            return result.isPortal();
    private static boolean isConclusiveResult(@NonNull CaptivePortalProbeResult result,
            @Nullable Uri captivePortalApiUrl) {
        // isPortal() is not expected on the HTTPS probe, but treat the network as portal would make
        // sense if the probe reports portal. In case the capport API is available, the API is
        // authoritative on whether there is a portal, so the HTTPS probe is not enough to conclude
        // there is connectivity, and a determination will be made once the capport API probe
        // returns. Note that the API can only force the system to detect a portal even if the HTTPS
        // probe succeeds. It cannot force the system to detect no portal if the HTTPS probe fails.
        return result.isPortal()
                || (result.isConcludedFromHttps() && result.isSuccessful()
                        && captivePortalApiUrl == null);
    }

    private void reportProbeResult(@NonNull CaptivePortalProbeResult res) {
        if (res instanceof CapportApiProbeResult) {
            maybeReportCaptivePortalData(((CapportApiProbeResult) res).getCaptivePortalData());
        }

        // This is not a if-else case since partial connectivity will concluded from both HTTP and
        // HTTPS probe. Both HTTP and HTTPS result should be reported.
        if (res.isConcludedFromHttps()) {
            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, res);
        }

        if (res.isConcludedFromHttp()) {
            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, res);
        }
    }

@@ -2314,9 +2339,10 @@ public class NetworkMonitor extends StateMachine {
        final CountDownLatch latch = new CountDownLatch(2);

        final Uri capportApiUrl = getCaptivePortalApiUrl(mLinkProperties);
        final HttpsProbeThread httpsProbe = new HttpsProbeThread(latch, proxy, httpsUrl,
                capportApiUrl);
        final HttpProbeThread httpProbe = new HttpProbeThread(latch, proxy, httpUrl, capportApiUrl);
        final ProbeThread httpsProbe = new ProbeThread(latch, proxy, httpsUrl,
                ValidationProbeEvent.PROBE_HTTPS, capportApiUrl);
        final ProbeThread httpProbe = new ProbeThread(latch, proxy, httpUrl,
                ValidationProbeEvent.PROBE_HTTP, capportApiUrl);

        try {
            httpsProbe.start();
@@ -2324,22 +2350,20 @@ public class NetworkMonitor extends StateMachine {
            latch.await(PROBE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            validationLog("Error: probes wait interrupted!");
            return CaptivePortalProbeResult.FAILED;
            return CaptivePortalProbeResult.failed(CaptivePortalProbeResult.PROBE_UNKNOWN);
        }

        final CaptivePortalProbeResult httpsResult = httpsProbe.result();
        final CaptivePortalProbeResult httpResult = httpProbe.result();

        // Look for a conclusive probe result first.
        if (httpProbe.isConclusiveResult(httpResult)) {
            maybeReportCaptivePortalData(httpProbe.getCaptivePortalData());
            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpResult);
        if (isConclusiveResult(httpResult, capportApiUrl)) {
            reportProbeResult(httpProbe.result());
            return httpResult;
        }

        if (httpsProbe.isConclusiveResult(httpsResult)) {
            maybeReportCaptivePortalData(httpProbe.getCaptivePortalData());
            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsResult);
        if (isConclusiveResult(httpsResult, capportApiUrl)) {
            reportProbeResult(httpsProbe.result());
            return httpsResult;
        }
        // Consider a DNS response with a private IP address on the HTTP probe as an indication that
@@ -2350,7 +2374,7 @@ public class NetworkMonitor extends StateMachine {
        // probe should not be delayed by this check.
        if (mPrivateIpNoInternetEnabled && (httpResult.isDnsPrivateIpResponse())) {
            validationLog("DNS response to the URL is private IP");
            return CaptivePortalProbeResult.FAILED;
            return CaptivePortalProbeResult.failed(1 << ValidationProbeEvent.PROBE_HTTP);
        }
        // If a fallback method exists, use it to retry portal detection.
        // If we have new-style probe specs, use those. Otherwise, use the fallback URLs.
@@ -2367,8 +2391,7 @@ public class NetworkMonitor extends StateMachine {
        // Otherwise wait until http and https probes completes and use their results.
        try {
            httpProbe.join();
            maybeReportCaptivePortalData(httpProbe.getCaptivePortalData());
            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpProbe.result());
            reportProbeResult(httpProbe.result());

            if (httpProbe.result().isPortal()) {
                return httpProbe.result();
@@ -2386,7 +2409,7 @@ public class NetworkMonitor extends StateMachine {
            return httpsProbe.result();
        } catch (InterruptedException e) {
            validationLog("Error: http or https probe wait interrupted!");
            return CaptivePortalProbeResult.FAILED;
            return CaptivePortalProbeResult.failed(CaptivePortalProbeResult.PROBE_UNKNOWN);
        }
    }

+17 −4

File changed.

Preview size limit exceeded, changes collapsed.

Loading