Make NET_CAPABILITY_VALIDATED (almost) a first-class citizen.
1. Always keep ConnectivityService's validated bits current:
- Apply the validated bit whenever a NetworkAgent updates its
NetworkCapabilities.
- Set or clear the validated bit whenever lastValidated changes.
2. Send callbacks when the validation state of a network changes.
3. Delete getNetworkCapabilitiesAndValidation, removing code
duplication with getNetworkCapabilities.
4. Add the validated bit to NetworkCapabilities#toString.
Bug: 18591282
Bug: 20081183
Change-Id: I6aa53b61c15cc137f203f9fc6bbd4c16894be750
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 02bffc4..36baa0b1f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1071,23 +1071,6 @@
}
}
- private NetworkCapabilities getNetworkCapabilitiesAndValidation(NetworkAgentInfo nai) {
- if (nai != null) {
- synchronized (nai) {
- if (nai.created) {
- NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
- if (nai.lastValidated) {
- nc.addCapability(NET_CAPABILITY_VALIDATED);
- } else {
- nc.removeCapability(NET_CAPABILITY_VALIDATED);
- }
- return nc;
- }
- }
- }
- return null;
- }
-
@Override
public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
// The basic principle is: if an app's traffic could possibly go over a
@@ -1109,7 +1092,7 @@
HashMap<Network, NetworkCapabilities> result = new HashMap<Network, NetworkCapabilities>();
NetworkAgentInfo nai = getDefaultNetwork();
- NetworkCapabilities nc = getNetworkCapabilitiesAndValidation(getDefaultNetwork());
+ NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
if (nc != null) {
result.put(nai.network, nc);
}
@@ -1122,9 +1105,9 @@
if (networks != null) {
for (Network network : networks) {
nai = getNetworkAgentInfoForNetwork(network);
- nc = getNetworkCapabilitiesAndValidation(nai);
+ nc = getNetworkCapabilitiesInternal(nai);
if (nc != null) {
- result.put(nai.network, nc);
+ result.put(network, nc);
}
}
}
@@ -1184,25 +1167,24 @@
return null;
}
- @Override
- public NetworkCapabilities getNetworkCapabilities(Network network) {
- enforceAccessPermission();
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) {
if (nai != null) {
synchronized (nai) {
- NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
- if (nai.lastValidated) {
- nc.addCapability(NET_CAPABILITY_VALIDATED);
- } else {
- nc.removeCapability(NET_CAPABILITY_VALIDATED);
+ if (nai.networkCapabilities != null) {
+ return new NetworkCapabilities(nai.networkCapabilities);
}
- return nc;
}
}
return null;
}
@Override
+ public NetworkCapabilities getNetworkCapabilities(Network network) {
+ enforceAccessPermission();
+ return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
+ }
+
+ @Override
public NetworkState[] getAllNetworkState() {
// Require internal since we're handing out IMSI details
enforceConnectivityInternalPermission();
@@ -1950,11 +1932,14 @@
}
case NetworkMonitor.EVENT_NETWORK_TESTED: {
NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
- if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) {
- boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
+ if (isLiveNetworkAgent(nai, "EVENT_NETWORK_TESTED")) {
+ final boolean valid =
+ (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
+ final boolean validationChanged = (valid != nai.lastValidated);
nai.lastValidated = valid;
if (valid) {
if (DBG) log("Validated " + nai.name());
+ nai.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
if (!nai.everValidated) {
nai.everValidated = true;
rematchNetworkAndRequests(nai, NascentState.JUST_VALIDATED,
@@ -1962,6 +1947,8 @@
// If score has changed, rebroadcast to NetworkFactories. b/17726566
sendUpdatedScoreToFactories(nai);
}
+ } else {
+ nai.networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED);
}
updateInetCondition(nai);
// Let the NetworkAgent know the state of its network
@@ -1970,8 +1957,9 @@
(valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
0, null);
- // TODO: trigger a NetworkCapabilities update so that the dialog can know
- // that the network is now validated and close itself.
+ if (validationChanged) {
+ notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
+ }
}
break;
}
@@ -3534,8 +3522,7 @@
}
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
- if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
- == false) {
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
enforceConnectivityInternalPermission();
} else {
enforceChangePermission();
@@ -3562,8 +3549,7 @@
private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
// if UID is restricted, don't allow them to bring up metered APNs
- if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)
- == false) {
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED) == false) {
final int uidRules;
final int uid = Binder.getCallingUid();
synchronized(mRulesLock) {
@@ -3934,6 +3920,11 @@
synchronized (networkAgent) {
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());
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED);
}