Add NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL

Bug: 21343774
Bug: 20898908
Change-Id: I23069a6cba346999d1b2eeaa445023bd6bf4ef94
This commit is contained in:
Paul Jensen
2015-06-16 14:27:36 -04:00
parent fd62bcfdca
commit 53f089581a
3 changed files with 47 additions and 15 deletions

View File

@@ -176,8 +176,14 @@ public final class NetworkCapabilities implements Parcelable {
*/ */
public static final int NET_CAPABILITY_VALIDATED = 16; public static final int NET_CAPABILITY_VALIDATED = 16;
/**
* Indicates that this network was found to have a captive portal in place last time it was
* probed.
*/
public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_VALIDATED; private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL;
/** /**
* Adds the given capability to this {@code NetworkCapability} instance. * Adds the given capability to this {@code NetworkCapability} instance.

View File

@@ -23,6 +23,7 @@ import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.ConnectivityManager.isNetworkTypeValid;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
@@ -1993,18 +1994,24 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: { case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
final int netId = msg.arg2; final int netId = msg.arg2;
if (msg.arg1 == 0) { final boolean visible = (msg.arg1 != 0);
final NetworkAgentInfo nai;
synchronized (mNetworkForNetId) {
nai = mNetworkForNetId.get(netId);
}
// If captive portal status has changed, update capabilities.
if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
nai.lastCaptivePortalDetected = visible;
nai.everCaptivePortalDetected |= visible;
updateCapabilities(nai, nai.networkCapabilities);
}
if (!visible) {
setProvNotificationVisibleIntent(false, netId, null, 0, null, null); setProvNotificationVisibleIntent(false, netId, null, 0, null, null);
} else { } else {
final NetworkAgentInfo nai;
synchronized (mNetworkForNetId) {
nai = mNetworkForNetId.get(netId);
}
if (nai == null) { if (nai == null) {
loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
break; break;
} }
nai.captivePortalDetected = true;
setProvNotificationVisibleIntent(true, netId, NotificationType.SIGN_IN, setProvNotificationVisibleIntent(true, netId, NotificationType.SIGN_IN,
nai.networkInfo.getType(),nai.networkInfo.getExtraInfo(), nai.networkInfo.getType(),nai.networkInfo.getExtraInfo(),
(PendingIntent)msg.obj); (PendingIntent)msg.obj);
@@ -2426,7 +2433,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Only prompt if the network is unvalidated and was explicitly selected by the user, and if // Only prompt if the network is unvalidated and was explicitly selected by the user, and if
// we haven't already been told to switch to it regardless of whether it validated or not. // we haven't already been told to switch to it regardless of whether it validated or not.
// Also don't prompt on captive portals because we're already prompting the user to sign in. // Also don't prompt on captive portals because we're already prompting the user to sign in.
if (nai == null || nai.everValidated || nai.captivePortalDetected || if (nai == null || nai.everValidated || nai.everCaptivePortalDetected ||
!nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) { !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) {
return; return;
} }
@@ -4046,17 +4053,32 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNumDnsEntries = last; mNumDnsEntries = last;
} }
/**
* Update the NetworkCapabilities for {@code networkAgent} to {@code networkCapabilities}
* augmented with any stateful capabilities implied from {@code networkAgent}
* (e.g., validated status and captive portal status).
*
* @param networkAgent the network having its capabilities updated.
* @param networkCapabilities the new network capabilities.
*/
private void updateCapabilities(NetworkAgentInfo networkAgent, private void updateCapabilities(NetworkAgentInfo networkAgent,
NetworkCapabilities networkCapabilities) { NetworkCapabilities networkCapabilities) {
// Don't modify caller's NetworkCapabilities.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
if (networkAgent.lastValidated) {
networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
} else {
networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED);
}
if (networkAgent.lastCaptivePortalDetected) {
networkCapabilities.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
} else {
networkCapabilities.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
}
if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) { if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) {
synchronized (networkAgent) { synchronized (networkAgent) {
networkAgent.networkCapabilities = networkCapabilities; networkAgent.networkCapabilities = networkCapabilities;
} }
if (networkAgent.lastValidated) {
networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
// There's no need to remove the capability if we think the network is unvalidated,
// because NetworkAgents don't set the validated capability.
}
rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore()); rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore());
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED); notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED);
} }

View File

@@ -66,7 +66,10 @@ public class NetworkAgentInfo {
// Whether a captive portal was ever detected on this network. // Whether a captive portal was ever detected on this network.
// This is a sticky bit; once set it is never cleared. // This is a sticky bit; once set it is never cleared.
public boolean captivePortalDetected; public boolean everCaptivePortalDetected;
// Whether a captive portal was found during the last network validation attempt.
public boolean lastCaptivePortalDetected;
// This represents the last score received from the NetworkAgent. // This represents the last score received from the NetworkAgent.
private int currentScore; private int currentScore;
@@ -174,7 +177,8 @@ public class NetworkAgentInfo {
"created{" + created + "} " + "created{" + created + "} " +
"explicitlySelected{" + networkMisc.explicitlySelected + "} " + "explicitlySelected{" + networkMisc.explicitlySelected + "} " +
"acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " + "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " +
"captivePortalDetected{" + captivePortalDetected + "} " + "everCaptivePortalDetected{" + everCaptivePortalDetected + "} " +
"lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} " +
"}"; "}";
} }