Merge "Update multiple validation result to ConnectivityService"
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b3b5e45..7fa9c6e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -25,8 +25,8 @@
import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeValid;
-import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
-import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -2603,21 +2603,12 @@
final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
if (nai == null) break;
- final boolean partialConnectivity =
- (msg.arg1 == NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY)
- || (nai.networkMisc.acceptPartialConnectivity
- && nai.partialConnectivity);
- // Once a network is determined to have partial connectivity, it cannot
- // go back to full connectivity without a disconnect. This is because
- // NetworkMonitor can only communicate either PARTIAL_CONNECTIVITY or VALID,
- // but not both.
- // TODO: Provide multi-testResult to improve the communication between
- // ConnectivityService and NetworkMonitor, so that ConnectivityService could
- // know the real status of network.
+ final boolean wasPartial = nai.partialConnectivity;
+ nai.partialConnectivity = ((msg.arg1 & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
final boolean partialConnectivityChanged =
- (partialConnectivity && !nai.partialConnectivity);
+ (wasPartial != nai.partialConnectivity);
- final boolean valid = (msg.arg1 == NETWORK_TEST_RESULT_VALID);
+ final boolean valid = ((msg.arg1 & NETWORK_VALIDATION_RESULT_VALID) != 0);
final boolean wasValidated = nai.lastValidated;
final boolean wasDefault = isDefaultNetwork(nai);
if (nai.everCaptivePortalDetected && !nai.captivePortalLoginNotified
@@ -2647,21 +2638,23 @@
if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
if (valid) {
handleFreshlyValidatedNetwork(nai);
- // Clear NO_INTERNET and LOST_INTERNET notifications if network becomes
- // valid.
+ // Clear NO_INTERNET, PARTIAL_CONNECTIVITY and LOST_INTERNET
+ // notifications if network becomes valid.
mNotifier.clearNotification(nai.network.netId,
NotificationType.NO_INTERNET);
mNotifier.clearNotification(nai.network.netId,
NotificationType.LOST_INTERNET);
+ mNotifier.clearNotification(nai.network.netId,
+ NotificationType.PARTIAL_CONNECTIVITY);
}
} else if (partialConnectivityChanged) {
- nai.partialConnectivity = partialConnectivity;
updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
}
updateInetCondition(nai);
// Let the NetworkAgent know the state of its network
Bundle redirectUrlBundle = new Bundle();
redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, redirectUrl);
+ // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
nai.asyncChannel.sendMessage(
NetworkAgent.CMD_REPORT_NETWORK_STATUS,
(valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
@@ -3441,6 +3434,9 @@
// Inform NetworkMonitor that partial connectivity is acceptable. This will likely
// result in a partial connectivity result which will be processed by
// maybeHandleNetworkMonitorMessage.
+ //
+ // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
+ // per network. Therefore, NetworkMonitor may still do https probe.
try {
nai.networkMonitor().setAcceptPartialConnectivity();
} catch (RemoteException e) {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 5934fcb..3dcd610 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -30,9 +30,12 @@
import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_VPN;
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.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
+import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
@@ -443,6 +446,16 @@
}
private class MockNetworkAgent {
+ private static final int VALIDATION_RESULT_BASE = NETWORK_VALIDATION_PROBE_DNS
+ | NETWORK_VALIDATION_PROBE_HTTP
+ | NETWORK_VALIDATION_PROBE_HTTPS;
+ private static final int VALIDATION_RESULT_VALID = VALIDATION_RESULT_BASE
+ | NETWORK_VALIDATION_RESULT_VALID;
+ private static final int VALIDATION_RESULT_PARTIAL = VALIDATION_RESULT_BASE
+ | NETWORK_VALIDATION_PROBE_FALLBACK
+ | NETWORK_VALIDATION_RESULT_PARTIAL;
+ private static final int VALIDATION_RESULT_INVALID = 0;
+
private final INetworkMonitor mNetworkMonitor;
private final NetworkInfo mNetworkInfo;
private final NetworkCapabilities mNetworkCapabilities;
@@ -460,17 +473,17 @@
private String mRedirectUrl;
private INetworkMonitorCallbacks mNmCallbacks;
- private int mNmValidationResult = NETWORK_TEST_RESULT_INVALID;
+ private int mNmValidationResult = VALIDATION_RESULT_BASE;
private String mNmValidationRedirectUrl = null;
private boolean mNmProvNotificationRequested = false;
void setNetworkValid() {
- mNmValidationResult = NETWORK_TEST_RESULT_VALID;
+ mNmValidationResult = VALIDATION_RESULT_VALID;
mNmValidationRedirectUrl = null;
}
void setNetworkInvalid() {
- mNmValidationResult = NETWORK_TEST_RESULT_INVALID;
+ mNmValidationResult = VALIDATION_RESULT_INVALID;
mNmValidationRedirectUrl = null;
}
@@ -480,7 +493,12 @@
}
void setNetworkPartial() {
- mNmValidationResult = NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
+ mNmValidationResult = VALIDATION_RESULT_PARTIAL;
+ mNmValidationRedirectUrl = null;
+ }
+
+ void setNetworkPartialValid() {
+ mNmValidationResult = VALIDATION_RESULT_PARTIAL | VALIDATION_RESULT_VALID;
mNmValidationRedirectUrl = null;
}
@@ -597,7 +615,7 @@
private void onValidationRequested() {
try {
if (mNmProvNotificationRequested
- && mNmValidationResult == NETWORK_TEST_RESULT_VALID) {
+ && mNmValidationResult == VALIDATION_RESULT_VALID) {
mNmCallbacks.hideProvisioningNotification();
mNmProvNotificationRequested = false;
}
@@ -2651,7 +2669,7 @@
// With HTTPS probe disabled, NetworkMonitor should pass the network validation with http
// probe.
- mWiFiNetworkAgent.setNetworkValid();
+ mWiFiNetworkAgent.setNetworkPartialValid();
// If the user chooses yes to use this partial connectivity wifi, switch the default
// network to wifi and check if wifi becomes valid or not.
mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
@@ -2749,6 +2767,54 @@
}
@Test
+ public void testCaptivePortalOnPartialConnectivity() throws RemoteException {
+ final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
+ final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
+ mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
+
+ final TestNetworkCallback validatedCallback = new TestNetworkCallback();
+ final NetworkRequest validatedRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_VALIDATED).build();
+ mCm.registerNetworkCallback(validatedRequest, validatedCallback);
+
+ // Bring up a network with a captive portal.
+ // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ String firstRedirectUrl = "http://example.com/firstPath";
+ mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
+ captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
+
+ // Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
+ mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork());
+ verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1))
+ .launchCaptivePortalApp();
+
+ // Report that the captive portal is dismissed with partial connectivity, and check that
+ // callbacks are fired.
+ mWiFiNetworkAgent.setNetworkPartial();
+ mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
+ waitForIdle();
+ captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+ mWiFiNetworkAgent);
+
+ // Report partial connectivity is accepted.
+ mWiFiNetworkAgent.setNetworkPartialValid();
+ mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
+ false /* always */);
+ waitForIdle();
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+ validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
+ NetworkCapabilities nc =
+ validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+ mWiFiNetworkAgent);
+
+ mCm.unregisterNetworkCallback(captivePortalCallback);
+ mCm.unregisterNetworkCallback(validatedCallback);
+ }
+
+ @Test
public void testCaptivePortal() {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()