Merge changes I31d5260d,Ied92f558 into nyc-dev am: c58c9ae0a9
am: 31b3676cce * commit '31b3676ccec847b1e86c23b2f5073dc1cc83abf4': Start VPN as early as possible during startup Split network agent created state from connected state Change-Id: I6bb605a83b96a3efab36ab6a7bdb5859e1eafea8
This commit is contained in:
@@ -741,7 +741,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
//set up the listener for user state for creating user VPNs
|
//set up the listener for user state for creating user VPNs
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(Intent.ACTION_USER_STARTING);
|
intentFilter.addAction(Intent.ACTION_USER_STARTED);
|
||||||
intentFilter.addAction(Intent.ACTION_USER_STOPPED);
|
intentFilter.addAction(Intent.ACTION_USER_STOPPED);
|
||||||
intentFilter.addAction(Intent.ACTION_USER_ADDED);
|
intentFilter.addAction(Intent.ACTION_USER_ADDED);
|
||||||
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
|
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
|
||||||
@@ -1979,7 +1979,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
|
networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
|
||||||
Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
|
Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
|
||||||
}
|
}
|
||||||
if (nai.created && !nai.networkCapabilities.equalImmutableCapabilities(
|
if (nai.everConnected && !nai.networkCapabilities.equalImmutableCapabilities(
|
||||||
networkCapabilities)) {
|
networkCapabilities)) {
|
||||||
Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: "
|
Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: "
|
||||||
+ nai.networkCapabilities + " -> " + networkCapabilities);
|
+ nai.networkCapabilities + " -> " + networkCapabilities);
|
||||||
@@ -1990,13 +1990,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
|
case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
log("Update of LinkProperties for " + nai.name() +
|
log("Update of LinkProperties for " + nai.name() +
|
||||||
"; created=" + nai.created);
|
"; created=" + nai.created +
|
||||||
|
"; everConnected=" + nai.everConnected);
|
||||||
}
|
}
|
||||||
LinkProperties oldLp = nai.linkProperties;
|
LinkProperties oldLp = nai.linkProperties;
|
||||||
synchronized (nai) {
|
synchronized (nai) {
|
||||||
nai.linkProperties = (LinkProperties)msg.obj;
|
nai.linkProperties = (LinkProperties)msg.obj;
|
||||||
}
|
}
|
||||||
if (nai.created) updateLinkProperties(nai, oldLp);
|
if (nai.everConnected) updateLinkProperties(nai, oldLp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
|
case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
|
||||||
@@ -2028,8 +2029,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
|
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
|
||||||
if (nai.created && !nai.networkMisc.explicitlySelected) {
|
if (nai.everConnected && !nai.networkMisc.explicitlySelected) {
|
||||||
loge("ERROR: created network explicitly selected.");
|
loge("ERROR: already-connected network explicitly selected.");
|
||||||
}
|
}
|
||||||
nai.networkMisc.explicitlySelected = true;
|
nai.networkMisc.explicitlySelected = true;
|
||||||
nai.networkMisc.acceptUnvalidated = (boolean) msg.obj;
|
nai.networkMisc.acceptUnvalidated = (boolean) msg.obj;
|
||||||
@@ -2314,7 +2315,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// This is whether it is satisfying any NetworkRequests or were it to become validated,
|
// This is whether it is satisfying any NetworkRequests or were it to become validated,
|
||||||
// would it have a chance of satisfying any NetworkRequests.
|
// would it have a chance of satisfying any NetworkRequests.
|
||||||
private boolean unneeded(NetworkAgentInfo nai) {
|
private boolean unneeded(NetworkAgentInfo nai) {
|
||||||
if (!nai.created || nai.isVPN() || nai.lingering) return false;
|
if (!nai.everConnected || nai.isVPN() || nai.lingering) return false;
|
||||||
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||||
// If this Network is already the highest scoring Network for a request, or if
|
// If this Network is already the highest scoring Network for a request, or if
|
||||||
// there is hope for it to become one if it validated, then it is needed.
|
// there is hope for it to become one if it validated, then it is needed.
|
||||||
@@ -2798,9 +2799,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
") by " + uid);
|
") by " + uid);
|
||||||
}
|
}
|
||||||
synchronized (nai) {
|
synchronized (nai) {
|
||||||
// Validating an uncreated network could result in a call to rematchNetworkAndRequests()
|
// Validating a network that has not yet connected could result in a call to
|
||||||
// which isn't meant to work on uncreated networks.
|
// rematchNetworkAndRequests() which is not meant to work on such networks.
|
||||||
if (!nai.created) return;
|
if (!nai.everConnected) return;
|
||||||
|
|
||||||
if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, false)) return;
|
if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, false)) return;
|
||||||
|
|
||||||
@@ -3699,7 +3700,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
|
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
|
||||||
if (userId == UserHandle.USER_NULL) return;
|
if (userId == UserHandle.USER_NULL) return;
|
||||||
|
|
||||||
if (Intent.ACTION_USER_STARTING.equals(action)) {
|
if (Intent.ACTION_USER_STARTED.equals(action)) {
|
||||||
onUserStart(userId);
|
onUserStart(userId);
|
||||||
} else if (Intent.ACTION_USER_STOPPED.equals(action)) {
|
} else if (Intent.ACTION_USER_STOPPED.equals(action)) {
|
||||||
onUserStop(userId);
|
onUserStop(userId);
|
||||||
@@ -4542,7 +4543,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// validated) of becoming the highest scoring network.
|
// validated) of becoming the highest scoring network.
|
||||||
private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
|
private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
|
||||||
ReapUnvalidatedNetworks reapUnvalidatedNetworks) {
|
ReapUnvalidatedNetworks reapUnvalidatedNetworks) {
|
||||||
if (!newNetwork.created) return;
|
if (!newNetwork.everConnected) return;
|
||||||
boolean keep = newNetwork.isVPN();
|
boolean keep = newNetwork.isVPN();
|
||||||
boolean isNewDefault = false;
|
boolean isNewDefault = false;
|
||||||
NetworkAgentInfo oldDefaultNetwork = null;
|
NetworkAgentInfo oldDefaultNetwork = null;
|
||||||
@@ -4841,7 +4842,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
" to " + state);
|
" to " + state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == NetworkInfo.State.CONNECTED && !networkAgent.created) {
|
if (!networkAgent.created
|
||||||
|
&& (state == NetworkInfo.State.CONNECTED
|
||||||
|
|| (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
|
||||||
try {
|
try {
|
||||||
// This should never fail. Specifying an already in use NetID will cause failure.
|
// This should never fail. Specifying an already in use NetID will cause failure.
|
||||||
if (networkAgent.isVPN()) {
|
if (networkAgent.isVPN()) {
|
||||||
@@ -4861,6 +4864,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
networkAgent.created = true;
|
networkAgent.created = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
|
||||||
|
networkAgent.everConnected = true;
|
||||||
|
|
||||||
updateLinkProperties(networkAgent, null);
|
updateLinkProperties(networkAgent, null);
|
||||||
notifyIfacesChangedForNetworkStats();
|
notifyIfacesChangedForNetworkStats();
|
||||||
|
|
||||||
|
|||||||
@@ -48,15 +48,21 @@ import java.util.Comparator;
|
|||||||
// 1. registered, uncreated, disconnected, unvalidated
|
// 1. registered, uncreated, disconnected, unvalidated
|
||||||
// This state is entered when a NetworkFactory registers a NetworkAgent in any state except
|
// This state is entered when a NetworkFactory registers a NetworkAgent in any state except
|
||||||
// the CONNECTED state.
|
// the CONNECTED state.
|
||||||
// 2. registered, uncreated, connected, unvalidated
|
// 2. registered, uncreated, connecting, unvalidated
|
||||||
// This state is entered when a registered NetworkAgent transitions to the CONNECTED state
|
// This state is entered when a registered NetworkAgent for a VPN network transitions to the
|
||||||
// ConnectivityService will tell netd to create the network and immediately transition to
|
// CONNECTING state (TODO: go through this state for every network, not just VPNs).
|
||||||
// state #3.
|
// ConnectivityService will tell netd to create the network early in order to add extra UID
|
||||||
// 3. registered, created, connected, unvalidated
|
// routing rules referencing the netID. These rules need to be in place before the network is
|
||||||
|
// connected to avoid racing against client apps trying to connect to a half-setup network.
|
||||||
|
// 3. registered, uncreated, connected, unvalidated
|
||||||
|
// This state is entered when a registered NetworkAgent transitions to the CONNECTED state.
|
||||||
|
// ConnectivityService will tell netd to create the network if it was not already created, and
|
||||||
|
// immediately transition to state #4.
|
||||||
|
// 4. registered, created, connected, unvalidated
|
||||||
// If this network can satisfy the default NetworkRequest, then NetworkMonitor will
|
// If this network can satisfy the default NetworkRequest, then NetworkMonitor will
|
||||||
// probe for Internet connectivity.
|
// probe for Internet connectivity.
|
||||||
// If this network cannot satisfy the default NetworkRequest, it will immediately be
|
// If this network cannot satisfy the default NetworkRequest, it will immediately be
|
||||||
// transitioned to state #4.
|
// transitioned to state #5.
|
||||||
// A network may remain in this state if NetworkMonitor fails to find Internet connectivity,
|
// A network may remain in this state if NetworkMonitor fails to find Internet connectivity,
|
||||||
// for example:
|
// for example:
|
||||||
// a. a captive portal is present, or
|
// a. a captive portal is present, or
|
||||||
@@ -64,14 +70,14 @@ import java.util.Comparator;
|
|||||||
// c. a wireless connection stops transfering packets temporarily (e.g. device is in elevator
|
// c. a wireless connection stops transfering packets temporarily (e.g. device is in elevator
|
||||||
// or tunnel) but does not disconnect from the AP/cell tower, or
|
// or tunnel) but does not disconnect from the AP/cell tower, or
|
||||||
// d. a stand-alone device offering a WiFi AP without an uplink for configuration purposes.
|
// d. a stand-alone device offering a WiFi AP without an uplink for configuration purposes.
|
||||||
// 4. registered, created, connected, validated
|
// 5. registered, created, connected, validated
|
||||||
//
|
//
|
||||||
// The device's default network connection:
|
// The device's default network connection:
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// Networks in states #3 and #4 may be used as a device's default network connection if they
|
// Networks in states #4 and #5 may be used as a device's default network connection if they
|
||||||
// satisfy the default NetworkRequest.
|
// satisfy the default NetworkRequest.
|
||||||
// A network, that satisfies the default NetworkRequest, in state #4 should always be chosen
|
// A network, that satisfies the default NetworkRequest, in state #5 should always be chosen
|
||||||
// in favor of a network, that satisfies the default NetworkRequest, in state #3.
|
// in favor of a network, that satisfies the default NetworkRequest, in state #4.
|
||||||
// When deciding between two networks, that both satisfy the default NetworkRequest, to select
|
// When deciding between two networks, that both satisfy the default NetworkRequest, to select
|
||||||
// for the default network connection, the one with the higher score should be chosen.
|
// for the default network connection, the one with the higher score should be chosen.
|
||||||
//
|
//
|
||||||
@@ -83,14 +89,14 @@ import java.util.Comparator;
|
|||||||
// c. airplane mode is turned on, or
|
// c. airplane mode is turned on, or
|
||||||
// d. a wireless connection disconnects from AP/cell tower entirely (e.g. device is out of range
|
// d. a wireless connection disconnects from AP/cell tower entirely (e.g. device is out of range
|
||||||
// of AP for an extended period of time, or switches to another AP without roaming)
|
// of AP for an extended period of time, or switches to another AP without roaming)
|
||||||
// then that network can transition from any state (#1-#4) to unregistered. This happens by
|
// then that network can transition from any state (#1-#5) to unregistered. This happens by
|
||||||
// the transport disconnecting their NetworkAgent's AsyncChannel with ConnectivityManager.
|
// the transport disconnecting their NetworkAgent's AsyncChannel with ConnectivityManager.
|
||||||
// ConnectivityService also tells netd to destroy the network.
|
// ConnectivityService also tells netd to destroy the network.
|
||||||
//
|
//
|
||||||
// When ConnectivityService disconnects a network:
|
// When ConnectivityService disconnects a network:
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
// If a network has no chance of satisfying any requests (even if it were to become validated
|
// If a network has no chance of satisfying any requests (even if it were to become validated
|
||||||
// and enter state #4), ConnectivityService will disconnect the NetworkAgent's AsyncChannel.
|
// and enter state #5), ConnectivityService will disconnect the NetworkAgent's AsyncChannel.
|
||||||
// If the network ever for any period of time had satisfied a NetworkRequest (i.e. had been
|
// If the network ever for any period of time had satisfied a NetworkRequest (i.e. had been
|
||||||
// the highest scoring that satisfied the NetworkRequest's constraints), but is no longer the
|
// the highest scoring that satisfied the NetworkRequest's constraints), but is no longer the
|
||||||
// highest scoring network for any NetworkRequest, then there will be a 30s pause before
|
// highest scoring network for any NetworkRequest, then there will be a 30s pause before
|
||||||
@@ -110,10 +116,14 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
public NetworkCapabilities networkCapabilities;
|
public NetworkCapabilities networkCapabilities;
|
||||||
public final NetworkMonitor networkMonitor;
|
public final NetworkMonitor networkMonitor;
|
||||||
public final NetworkMisc networkMisc;
|
public final NetworkMisc networkMisc;
|
||||||
// Indicates if netd has been told to create this Network. Once created the appropriate routing
|
// Indicates if netd has been told to create this Network. From this point on the appropriate
|
||||||
// rules are setup and routes are added so packets can begin flowing over the Network.
|
// routing rules are setup and routes are added so packets can begin flowing over the 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 created;
|
public boolean created;
|
||||||
|
// Set to true after the first time this network is marked as CONNECTED. Once set, the network
|
||||||
|
// shows up in API calls, is able to satisfy NetworkRequests and can become the default network.
|
||||||
|
// This is a sticky bit; once set it is never cleared.
|
||||||
|
public boolean everConnected;
|
||||||
// Set to true if this Network successfully passed validation or if it did not satisfy the
|
// Set to true if this Network successfully passed validation or if it did not satisfy the
|
||||||
// default NetworkRequest in which case validation will not be attempted.
|
// default NetworkRequest in which case validation will not be attempted.
|
||||||
// This is a sticky bit; once set it is never cleared even if future validation attempts fail.
|
// This is a sticky bit; once set it is never cleared even if future validation attempts fail.
|
||||||
|
|||||||
Reference in New Issue
Block a user