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

Commit 3eed0abe authored by Chiachang Wang's avatar Chiachang Wang Committed by Automerger Merge Worker
Browse files

[MP01] Add configuration to support multiple probes am: 4adc781d am:...

[MP01] Add configuration to support multiple probes am: 4adc781d am: dc6e811a am: f245a6c6 am: c6243075 am: 62119620

Change-Id: I079240f1d933ecaf3cae2211cc55c5f763a4b319
parents f5508af5 62119620
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,10 @@
    </string-array>
    <string-array name="config_captive_portal_fallback_probe_specs" translatable="false">
    </string-array>
    <string-array name="config_captive_portal_http_urls" translatable="false">
    </string-array>
    <string-array name="config_captive_portal_https_urls" translatable="false">
    </string-array>

    <!-- Customized default DNS Servers address. -->
    <string-array name="config_default_dns_servers" translatable="false">
+23 −0
Original line number Diff line number Diff line
@@ -55,6 +55,18 @@ public class NetworkStackUtils {
    public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
            "captive_portal_other_fallback_urls";

    /**
     * A comma separated list of URLs used for captive portal detection in addition to the HTTP url
     * associated with the CAPTIVE_PORTAL_HTTP_URL settings.
     */
    public static final String CAPTIVE_PORTAL_OTHER_HTTP_URLS = "captive_portal_other_http_urls";

    /**
     * A comma separated list of URLs used for network validation. in addition to the HTTPS url
     * associated with the CAPTIVE_PORTAL_HTTPS_URL settings.
     */
    public static final String CAPTIVE_PORTAL_OTHER_HTTPS_URLS = "captive_portal_other_https_urls";

    /**
     * Which User-Agent string to use in the header of the captive portal detection probes.
     * The User-Agent field is unset when this setting has no value (HttpUrlConnection default).
@@ -111,6 +123,17 @@ public class NetworkStackUtils {
     */
    public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;

    /**
     * The default list of HTTP URLs to use for detecting captive portals.
     */
    public static final String[] DEFAULT_CAPTIVE_PORTAL_HTTP_URLS =
            new String [] {"http://connectivitycheck.gstatic.com/generate_204"};
    /**
     * The default list of HTTPS URLs for network validation, to use for confirming internet
     * connectivity.
     */
    public static final String[] DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS =
            new String [] {"https://www.google.com/generate_204"};
    /**
     * @deprecated Considering boolean experiment flag is likely to cause misconfiguration
     *             particularly when NetworkStack module rolls back to previous version. It's
+80 −23
Original line number Diff line number Diff line
@@ -63,8 +63,12 @@ import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_IGNORE;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_HTTPS_URLS;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_HTTP_URLS;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
import static android.net.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS;
import static android.net.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_HTTP_URLS;
import static android.net.util.NetworkStackUtils.DISMISS_PORTAL_IN_VALIDATED_NETWORK;
import static android.net.util.NetworkStackUtils.isEmpty;
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
@@ -358,9 +362,11 @@ public class NetworkMonitor extends StateMachine {
    private final TcpSocketTracker mTcpTracker;
    // Configuration values for captive portal detection probes.
    private final String mCaptivePortalUserAgent;
    private final URL mCaptivePortalHttpsUrl;
    private final URL mCaptivePortalHttpUrl;
    private final URL[] mCaptivePortalFallbackUrls;
    @NonNull
    private final URL[] mCaptivePortalHttpUrls;
    @NonNull
    private final URL[] mCaptivePortalHttpsUrls;
    @Nullable
    private final CaptivePortalProbeSpec[] mCaptivePortalFallbackSpecs;

@@ -480,8 +486,8 @@ public class NetworkMonitor extends StateMachine {
        mIsCaptivePortalCheckEnabled = getIsCaptivePortalCheckEnabled();
        mUseHttps = getUseHttpsValidation();
        mCaptivePortalUserAgent = getCaptivePortalUserAgent();
        mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl());
        mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl());
        mCaptivePortalHttpsUrls = makeCaptivePortalHttpsUrls();
        mCaptivePortalHttpUrls = makeCaptivePortalHttpUrls();
        mCaptivePortalFallbackUrls = makeCaptivePortalFallbackUrls();
        mCaptivePortalFallbackSpecs = makeCaptivePortalFallbackProbeSpecs();
        mRandom = deps.getRandom();
@@ -1594,19 +1600,8 @@ public class NetworkMonitor extends StateMachine {
        try {
            final String firstUrl = mDependencies.getSetting(mContext, CAPTIVE_PORTAL_FALLBACK_URL,
                    null);

            final URL[] settingProviderUrls;
            if (!TextUtils.isEmpty(firstUrl)) {
                final String otherUrls = mDependencies.getDeviceConfigProperty(
                        NAMESPACE_CONNECTIVITY, CAPTIVE_PORTAL_OTHER_FALLBACK_URLS, "");
                // otherUrls may be empty, but .split() ignores trailing empty strings
                final String separator = ",";
                final String[] urls = (firstUrl + separator + otherUrls).split(separator);
                settingProviderUrls = convertStrings(urls, this::makeURL, new URL[0]);
            } else {
                settingProviderUrls = new URL[0];
            }

            final URL[] settingProviderUrls =
                combineCaptivePortalUrls(firstUrl, CAPTIVE_PORTAL_OTHER_FALLBACK_URLS);
            return getProbeUrlArrayConfig(settingProviderUrls,
                    R.array.config_captive_portal_fallback_urls,
                    R.array.default_captive_portal_fallback_urls, this::makeURL);
@@ -1638,6 +1633,49 @@ public class NetworkMonitor extends StateMachine {
        }
    }

    private URL[] makeCaptivePortalHttpsUrls() {
        final String firstUrl = getCaptivePortalServerHttpsUrl();
        try {
            final URL[] settingProviderUrls =
                combineCaptivePortalUrls(firstUrl, CAPTIVE_PORTAL_OTHER_HTTPS_URLS);
            return getProbeUrlArrayConfig(settingProviderUrls,
                    R.array.config_captive_portal_https_urls,
                    DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS, this::makeURL);
        } catch (Exception e) {
            // Don't let a misconfiguration bootloop the system.
            Log.e(TAG, "Error parsing configured https URLs", e);
            // Ensure URL aligned with legacy configuration.
            return new URL[]{makeURL(firstUrl)};
        }
    }

    private URL[] makeCaptivePortalHttpUrls() {
        final String firstUrl = getCaptivePortalServerHttpUrl();
        try {
            final URL[] settingProviderUrls =
                    combineCaptivePortalUrls(firstUrl, CAPTIVE_PORTAL_OTHER_HTTP_URLS);
            return getProbeUrlArrayConfig(settingProviderUrls,
                    R.array.config_captive_portal_http_urls,
                    DEFAULT_CAPTIVE_PORTAL_HTTP_URLS, this::makeURL);
        } catch (Exception e) {
            // Don't let a misconfiguration bootloop the system.
            Log.e(TAG, "Error parsing configured http URLs", e);
            // Ensure URL aligned with legacy configuration.
            return new URL[]{makeURL(firstUrl)};
        }
    }

    private URL[] combineCaptivePortalUrls(final String firstUrl, final String name) {
        if (TextUtils.isEmpty(firstUrl)) return new URL[0];

        final String otherUrls = mDependencies.getDeviceConfigProperty(
                NAMESPACE_CONNECTIVITY, name, "");
        // otherUrls may be empty, but .split() ignores trailing empty strings
        final String separator = ",";
        final String[] urls = (firstUrl + separator + otherUrls).split(separator);
        return convertStrings(urls, this::makeURL, new URL[0]);
    }

    /**
     * Read a setting from a resource or the settings provider.
     *
@@ -1678,6 +1716,24 @@ public class NetworkMonitor extends StateMachine {
    private <T> T[] getProbeUrlArrayConfig(@NonNull T[] providerValue, @ArrayRes int configResId,
            @ArrayRes int defaultResId, @NonNull Function<String, T> resourceConverter) {
        final Resources res = getContextByMccIfNoSimCardOrDefault().getResources();
        return getProbeUrlArrayConfig(providerValue, configResId, res.getStringArray(defaultResId),
                resourceConverter);
    }

    /**
     * Get an array configuration from resources or the settings provider.
     *
     * <p>The configuration resource is prioritized, then the provider values, then the default
     * resource values.
     * @param providerValue Values obtained from the setting provider.
     * @param configResId ID of the configuration resource.
     * @param defaultConfig Values of default configuration.
     * @param resourceConverter Converter from the resource strings to stored setting class. Null
     *                          return values are ignored.
     */
    private <T> T[] getProbeUrlArrayConfig(@NonNull T[] providerValue, @ArrayRes int configResId,
            String[] defaultConfig, @NonNull Function<String, T> resourceConverter) {
        final Resources res = getContextByMccIfNoSimCardOrDefault().getResources();
        String[] configValue = res.getStringArray(configResId);

        if (configValue.length == 0) {
@@ -1685,7 +1741,7 @@ public class NetworkMonitor extends StateMachine {
                return providerValue;
            }

            configValue = res.getStringArray(defaultResId);
            configValue = defaultConfig;
        }

        return convertStrings(configValue, resourceConverter, Arrays.copyOf(providerValue, 0));
@@ -1746,8 +1802,8 @@ public class NetworkMonitor extends StateMachine {
        }

        URL pacUrl = null;
        URL httpsUrl = mCaptivePortalHttpsUrl;
        URL httpUrl = mCaptivePortalHttpUrl;
        final URL[] httpsUrls = mCaptivePortalHttpsUrls;
        final URL[] httpUrls = mCaptivePortalHttpUrls;

        // On networks with a PAC instead of fetching a URL that should result in a 204
        // response, we instead simply fetch the PAC script.  This is done for a few reasons:
@@ -1774,7 +1830,8 @@ public class NetworkMonitor extends StateMachine {
            }
        }

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

@@ -1786,9 +1843,9 @@ public class NetworkMonitor extends StateMachine {
            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
        } else if (mUseHttps) {
            // Probe results are reported inside sendParallelHttpProbes.
            result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
            result = sendParallelHttpProbes(proxyInfo, httpsUrls[0], httpUrls[0]);
        } else {
            result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
            result = sendDnsAndHttpProbes(proxyInfo, httpUrls[0], ValidationProbeEvent.PROBE_HTTP);
            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
        }