Updating Existing CS APIs for multiple defaults

Updating existing ConnectivityService APIs to support multiple default
network functionality.

Bug: 178729499
Bug: 172347841
Test: atest FrameworksNetTests
atest NetworkStackTests
atest FrameworksNetIntegrationTests
atest NetworkStackIntegrationTests
atest CtsNetTestCasesLatestSdk

Change-Id: Ic41fdc402a26809efda71f484c259ffd7a52e63b
This commit is contained in:
James Mattis
2021-01-31 17:06:19 -08:00
parent d31bdfaa0c
commit 2516da35fc

View File

@@ -1384,7 +1384,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
private NetworkState getUnfilteredActiveNetworkState(int uid) { private NetworkState getUnfilteredActiveNetworkState(int uid) {
NetworkAgentInfo nai = getDefaultNetwork(); NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
final Network[] networks = getVpnUnderlyingNetworks(uid); final Network[] networks = getVpnUnderlyingNetworks(uid);
if (networks != null) { if (networks != null) {
@@ -1517,7 +1517,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
NetworkAgentInfo nai = getDefaultNetwork(); NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid,
ignoreBlocked)) { ignoreBlocked)) {
return null; return null;
@@ -1656,21 +1656,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
HashMap<Network, NetworkCapabilities> result = new HashMap<>(); HashMap<Network, NetworkCapabilities> result = new HashMap<>();
final NetworkAgentInfo nai = getDefaultNetwork(); for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); if (!nri.isBeingSatisfied()) {
if (nc != null) { continue;
result.put( }
nai.network, final NetworkAgentInfo nai = nri.getSatisfier();
createWithLocationInfoSanitizedIfNecessaryWhenParceled( final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
nc, mDeps.getCallingUid(), callingPackageName)); if (null != nc
&& nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
&& !result.containsKey(nai.network)) {
result.put(
nai.network,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
nc, mDeps.getCallingUid(), callingPackageName));
}
} }
// No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null. // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
final Network[] networks = getVpnUnderlyingNetworks(Binder.getCallingUid()); final Network[] networks = getVpnUnderlyingNetworks(Binder.getCallingUid());
if (networks != null) { if (null != networks) {
for (Network network : networks) { for (final Network network : networks) {
nc = getNetworkCapabilitiesInternal(network); final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
if (nc != null) { if (null != nc) {
result.put( result.put(
network, network,
createWithLocationInfoSanitizedIfNecessaryWhenParceled( createWithLocationInfoSanitizedIfNecessaryWhenParceled(
@@ -1692,9 +1699,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
/** /**
* Return LinkProperties for the active (i.e., connected) default * Return LinkProperties for the active (i.e., connected) default
* network interface. It is assumed that at most one default network * network interface for the calling uid.
* is active at a time. If more than one is active, it is indeterminate
* which will be returned.
* @return the ip properties for the active network, or {@code null} if * @return the ip properties for the active network, or {@code null} if
* none is active * none is active
*/ */
@@ -3576,8 +3581,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
rematchAllNetworksAndRequests(); rematchAllNetworksAndRequests();
// If an active request exists, return as its score has already been sent if needed. // If the nri is satisfied, return as its score has already been sent if needed.
if (null != nri.getActiveRequest()) { if (nri.isBeingSatisfied()) {
return; return;
} }
@@ -3720,7 +3725,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (mNetworkRequests.get(nri.mRequests.get(0)) == null) { if (mNetworkRequests.get(nri.mRequests.get(0)) == null) {
return; return;
} }
if (nri.getActiveRequest() != null) { if (nri.isBeingSatisfied()) {
return; return;
} }
if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) { if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) {
@@ -4911,7 +4916,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
// the underlyingNetworks list. // the underlyingNetworks list.
if (underlyingNetworks == null) { if (underlyingNetworks == null) {
final NetworkAgentInfo defaultNai = getDefaultNetwork(); final NetworkAgentInfo defaultNai = getDefaultNetworkForUid(
nai.networkCapabilities.getOwnerUid());
if (defaultNai != null) { if (defaultNai != null) {
underlyingNetworks = new Network[] { defaultNai.network }; underlyingNetworks = new Network[] { defaultNai.network };
} }
@@ -4963,8 +4969,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
// TODO This needs to be the default network that applies to the NAI. // TODO This needs to be the default network that applies to the NAI.
private Network[] underlyingNetworksOrDefault(Network[] underlyingNetworks) { private Network[] underlyingNetworksOrDefault(final int ownerUid,
final Network defaultNetwork = getNetwork(getDefaultNetwork()); Network[] underlyingNetworks) {
final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid));
if (underlyingNetworks == null && defaultNetwork != null) { if (underlyingNetworks == null && defaultNetwork != null) {
// null underlying networks means to track the default. // null underlying networks means to track the default.
underlyingNetworks = new Network[] { defaultNetwork }; underlyingNetworks = new Network[] { defaultNetwork };
@@ -4977,7 +4984,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// TODO: support more than one level of underlying networks, either via a fixed-depth search // TODO: support more than one level of underlying networks, either via a fixed-depth search
// (e.g., 2 levels of underlying networks), or via loop detection, or.... // (e.g., 2 levels of underlying networks), or via loop detection, or....
if (!nai.supportsUnderlyingNetworks()) return false; if (!nai.supportsUnderlyingNetworks()) return false;
final Network[] underlying = underlyingNetworksOrDefault(nai.declaredUnderlyingNetworks); final Network[] underlying = underlyingNetworksOrDefault(
nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks);
return ArrayUtils.contains(underlying, network); return ArrayUtils.contains(underlying, network);
} }
@@ -5602,6 +5610,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
this(r, null); this(r, null);
} }
// True if this NRI is being satisfied. It also accounts for if the nri has its satisifer
// set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning
// false.
boolean isBeingSatisfied() {
return (null != mSatisfier && null != mActiveRequest);
}
boolean isMultilayerRequest() { boolean isMultilayerRequest() {
return mRequests.size() > 1; return mRequests.size() > 1;
} }
@@ -6131,12 +6146,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
@VisibleForTesting @VisibleForTesting
final NetworkAgentInfo mNoServiceNetwork; final NetworkAgentInfo mNoServiceNetwork;
// TODO: b/178729499 update this in favor of a method taking in a UID.
// The NetworkAgentInfo currently satisfying the default request, if any. // The NetworkAgentInfo currently satisfying the default request, if any.
private NetworkAgentInfo getDefaultNetwork() { private NetworkAgentInfo getDefaultNetwork() {
return mDefaultRequest.mSatisfier; return mDefaultRequest.mSatisfier;
} }
private NetworkAgentInfo getDefaultNetworkForUid(final int uid) {
for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
// Currently, all network requests will have the same uids therefore checking the first
// one is sufficient. If/when uids are tracked at the nri level, this can change.
final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUids();
if (null == uids) {
continue;
}
for (final UidRange range : uids) {
if (range.contains(uid)) {
return nri.getSatisfier();
}
}
}
return getDefaultNetwork();
}
@Nullable @Nullable
private Network getNetwork(@Nullable NetworkAgentInfo nai) { private Network getNetwork(@Nullable NetworkAgentInfo nai) {
return nai != null ? nai.network : null; return nai != null ? nai.network : null;
@@ -6643,7 +6674,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
@VisibleForTesting @VisibleForTesting
void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks, void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks,
@NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) { @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
underlyingNetworks = underlyingNetworksOrDefault(underlyingNetworks); underlyingNetworks = underlyingNetworksOrDefault(
agentCaps.getOwnerUid(), underlyingNetworks);
int[] transportTypes = agentCaps.getTransportTypes(); int[] transportTypes = agentCaps.getTransportTypes();
int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
@@ -8073,7 +8105,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
NetworkAgentInfo newDefaultAgent = null; NetworkAgentInfo newDefaultAgent = null;
if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) { if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) {
newDefaultAgent = getDefaultNetwork(); newDefaultAgent = mDefaultRequest.getSatisfier();
if (newDefaultAgent != null) { if (newDefaultAgent != null) {
intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
newDefaultAgent.networkInfo); newDefaultAgent.networkInfo);
@@ -8121,9 +8153,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
private Network[] getDefaultNetworks() { private Network[] getDefaultNetworks() {
ensureRunningOnConnectivityServiceThread(); ensureRunningOnConnectivityServiceThread();
final ArrayList<Network> defaultNetworks = new ArrayList<>(); final ArrayList<Network> defaultNetworks = new ArrayList<>();
final NetworkAgentInfo defaultNetwork = getDefaultNetwork(); final Set<Integer> activeNetIds = new ArraySet<>();
for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
if (nri.isBeingSatisfied()) {
activeNetIds.add(nri.getSatisfier().network().netId);
}
}
for (NetworkAgentInfo nai : mNetworkAgentInfos) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) { if (nai.everConnected && (activeNetIds.contains(nai.network().netId) || nai.isVPN())) {
defaultNetworks.add(nai.network); defaultNetworks.add(nai.network);
} }
} }