Loading res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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"> Loading src/android/net/util/NetworkStackUtils.java +23 −0 Original line number Diff line number Diff line Loading @@ -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). Loading Loading @@ -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 Loading src/com/android/server/connectivity/NetworkMonitor.java +80 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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. * Loading Loading @@ -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) { Loading @@ -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)); Loading Loading @@ -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: Loading @@ -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; } Loading @@ -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); } Loading Loading
res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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"> Loading
src/android/net/util/NetworkStackUtils.java +23 −0 Original line number Diff line number Diff line Loading @@ -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). Loading Loading @@ -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 Loading
src/com/android/server/connectivity/NetworkMonitor.java +80 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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. * Loading Loading @@ -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) { Loading @@ -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)); Loading Loading @@ -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: Loading @@ -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; } Loading @@ -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); } Loading