summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/com/android/server/NetworkStackService.java6
-rw-r--r--src/com/android/server/connectivity/NetworkMonitor.java40
-rw-r--r--tests/src/com/android/server/connectivity/NetworkMonitorTest.java33
3 files changed, 75 insertions, 4 deletions
diff --git a/src/com/android/server/NetworkStackService.java b/src/com/android/server/NetworkStackService.java
index 90db207..72955bb 100644
--- a/src/com/android/server/NetworkStackService.java
+++ b/src/com/android/server/NetworkStackService.java
@@ -253,6 +253,12 @@ public class NetworkStackService extends Service {
}
@Override
+ public void notifyAcceptPartialConnectivity() {
+ checkNetworkStackCallingPermission();
+ mNm.notifyAcceptPartialConnectivity();
+ }
+
+ @Override
public void forceReevaluation(int uid) {
checkNetworkStackCallingPermission();
mNm.forceReevaluation(uid);
diff --git a/src/com/android/server/connectivity/NetworkMonitor.java b/src/com/android/server/connectivity/NetworkMonitor.java
index c3447fd..fc56da7 100644
--- a/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/src/com/android/server/connectivity/NetworkMonitor.java
@@ -24,6 +24,7 @@ import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID;
+import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -227,6 +228,12 @@ public class NetworkMonitor extends StateMachine {
*/
public static final int EVENT_DNS_NOTIFICATION = 17;
+ /**
+ * ConnectivityService notifies NetworkMonitor that the user accepts partial connectivity and
+ * NetworkMonitor should ignore the https probe.
+ */
+ public static final int EVENT_ACCEPT_PARTIAL_CONNECTIVITY = 18;
+
// Start mReevaluateDelayMs at this value and double.
private static final int INITIAL_REEVALUATE_DELAY_MS = 1000;
private static final int MAX_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
@@ -379,6 +386,14 @@ public class NetworkMonitor extends StateMachine {
}
/**
+ * ConnectivityService notifies NetworkMonitor that the user accepts partial connectivity and
+ * NetworkMonitor should ignore the https probe.
+ */
+ public void notifyAcceptPartialConnectivity() {
+ sendMessage(EVENT_ACCEPT_PARTIAL_CONNECTIVITY);
+ }
+
+ /**
* Request the NetworkMonitor to reevaluate the network.
*/
public void forceReevaluation(int responsibleUid) {
@@ -636,6 +651,10 @@ public class NetworkMonitor extends StateMachine {
case EVENT_DNS_NOTIFICATION:
mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1);
break;
+ case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
+ mUseHttps = false;
+ transitionTo(mEvaluatingPrivateDnsState);
+ break;
default:
break;
}
@@ -1058,6 +1077,11 @@ public class NetworkMonitor extends StateMachine {
notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, probeResult.redirectUrl);
mLastPortalProbeResult = probeResult;
transitionTo(mCaptivePortalState);
+ } else if (probeResult.isPartialConnectivity()) {
+ logNetworkEvent(NetworkEvent.NETWORK_PARTIAL_CONNECTIVITY);
+ notifyNetworkTested(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY,
+ probeResult.redirectUrl);
+ transitionTo(mWaitingForNextProbeState);
} else {
logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, probeResult.redirectUrl);
@@ -1065,7 +1089,8 @@ public class NetworkMonitor extends StateMachine {
}
return HANDLED;
case EVENT_DNS_NOTIFICATION:
- // Leave the event to DefaultState to record correct dns timestamp.
+ case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
+ // Leave the event to DefaultState.
return NOT_HANDLED;
default:
// Wait for probe result and defer events to next state by default.
@@ -1504,10 +1529,11 @@ public class NetworkMonitor extends StateMachine {
// If we have new-style probe specs, use those. Otherwise, use the fallback URLs.
final CaptivePortalProbeSpec probeSpec = nextFallbackSpec();
final URL fallbackUrl = (probeSpec != null) ? probeSpec.getUrl() : nextFallbackUrl();
+ CaptivePortalProbeResult fallbackProbeResult = null;
if (fallbackUrl != null) {
- CaptivePortalProbeResult result = sendHttpProbe(fallbackUrl, PROBE_FALLBACK, probeSpec);
- if (result.isPortal()) {
- return result;
+ fallbackProbeResult = sendHttpProbe(fallbackUrl, PROBE_FALLBACK, probeSpec);
+ if (fallbackProbeResult.isPortal()) {
+ return fallbackProbeResult;
}
}
// Otherwise wait until http and https probes completes and use their results.
@@ -1517,6 +1543,12 @@ public class NetworkMonitor extends StateMachine {
return httpProbe.result();
}
httpsProbe.join();
+ final boolean isHttpSuccessful =
+ (httpProbe.result().isSuccessful()
+ || (fallbackProbeResult != null && fallbackProbeResult.isSuccessful()));
+ if (httpsProbe.result().isFailed() && isHttpSuccessful) {
+ return CaptivePortalProbeResult.PARTIAL;
+ }
return httpsProbe.result();
} catch (InterruptedException e) {
validationLog("Error: http or https probe wait interrupted!");
diff --git a/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index 34ca6ac..d93aef2 100644
--- a/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -18,6 +18,7 @@ package com.android.server.connectivity;
import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID;
+import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.provider.Settings.Global.DATA_STALL_EVALUATION_TYPE_DNS;
@@ -572,6 +573,34 @@ public class NetworkMonitorTest {
stats.build());
}
+ @Test
+ public void testIgnoreHttpsProbe() throws Exception {
+ setSslException(mHttpsConnection);
+ setStatus(mHttpConnection, 204);
+
+ final NetworkMonitor nm = makeMonitor();
+ nm.notifyNetworkConnected();
+ verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
+ .notifyNetworkTested(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY, null);
+
+ nm.notifyAcceptPartialConnectivity();
+ verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
+ .notifyNetworkTested(NETWORK_TEST_RESULT_VALID, null);
+ }
+
+ @Test
+ public void testIsPartialConnectivity() throws IOException {
+ setStatus(mHttpsConnection, 500);
+ setStatus(mHttpConnection, 204);
+ setStatus(mFallbackConnection, 500);
+ assertPartialConnectivity(makeMonitor().isCaptivePortal());
+
+ setStatus(mHttpsConnection, 500);
+ setStatus(mHttpConnection, 500);
+ setStatus(mFallbackConnection, 204);
+ assertPartialConnectivity(makeMonitor().isCaptivePortal());
+ }
+
private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
for (int i = 0; i < count; i++) {
wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
@@ -649,6 +678,10 @@ public class NetworkMonitorTest {
assertFalse(result.isSuccessful());
}
+ private void assertPartialConnectivity(CaptivePortalProbeResult result) {
+ assertTrue(result.isPartialConnectivity());
+ }
+
private void setSslException(HttpURLConnection connection) throws IOException {
doThrow(new SSLHandshakeException("Invalid cert")).when(connection).getResponseCode();
}