diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index e7301ccb6f..c21a78a5b1 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1384,7 +1384,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } private NetworkState getUnfilteredActiveNetworkState(int uid) { - NetworkAgentInfo nai = getDefaultNetwork(); + NetworkAgentInfo nai = getDefaultNetworkForUid(uid); final Network[] networks = getVpnUnderlyingNetworks(uid); 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, ignoreBlocked)) { return null; @@ -1656,21 +1656,28 @@ public class ConnectivityService extends IConnectivityManager.Stub HashMap result = new HashMap<>(); - final NetworkAgentInfo nai = getDefaultNetwork(); - NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); - if (nc != null) { - result.put( - nai.network, - createWithLocationInfoSanitizedIfNecessaryWhenParceled( - nc, mDeps.getCallingUid(), callingPackageName)); + for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { + if (!nri.isBeingSatisfied()) { + continue; + } + final NetworkAgentInfo nai = nri.getSatisfier(); + final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); + 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. final Network[] networks = getVpnUnderlyingNetworks(Binder.getCallingUid()); - if (networks != null) { - for (Network network : networks) { - nc = getNetworkCapabilitiesInternal(network); - if (nc != null) { + if (null != networks) { + for (final Network network : networks) { + final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); + if (null != nc) { result.put( network, createWithLocationInfoSanitizedIfNecessaryWhenParceled( @@ -1692,9 +1699,7 @@ public class ConnectivityService extends IConnectivityManager.Stub /** * Return LinkProperties for the active (i.e., connected) default - * network interface. It is assumed that at most one default network - * is active at a time. If more than one is active, it is indeterminate - * which will be returned. + * network interface for the calling uid. * @return the ip properties for the active network, or {@code null} if * none is active */ @@ -3576,8 +3581,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } } rematchAllNetworksAndRequests(); - // If an active request exists, return as its score has already been sent if needed. - if (null != nri.getActiveRequest()) { + // If the nri is satisfied, return as its score has already been sent if needed. + if (nri.isBeingSatisfied()) { return; } @@ -3720,7 +3725,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (mNetworkRequests.get(nri.mRequests.get(0)) == null) { return; } - if (nri.getActiveRequest() != null) { + if (nri.isBeingSatisfied()) { return; } 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 // the underlyingNetworks list. if (underlyingNetworks == null) { - final NetworkAgentInfo defaultNai = getDefaultNetwork(); + final NetworkAgentInfo defaultNai = getDefaultNetworkForUid( + nai.networkCapabilities.getOwnerUid()); if (defaultNai != null) { 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. - private Network[] underlyingNetworksOrDefault(Network[] underlyingNetworks) { - final Network defaultNetwork = getNetwork(getDefaultNetwork()); + private Network[] underlyingNetworksOrDefault(final int ownerUid, + Network[] underlyingNetworks) { + final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid)); if (underlyingNetworks == null && defaultNetwork != null) { // null underlying networks means to track the default. 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 // (e.g., 2 levels of underlying networks), or via loop detection, or.... 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); } @@ -5602,6 +5610,13 @@ public class ConnectivityService extends IConnectivityManager.Stub 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() { return mRequests.size() > 1; } @@ -6131,12 +6146,28 @@ public class ConnectivityService extends IConnectivityManager.Stub @VisibleForTesting 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. private NetworkAgentInfo getDefaultNetwork() { 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 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 private Network getNetwork(@Nullable NetworkAgentInfo nai) { return nai != null ? nai.network : null; @@ -6643,7 +6674,8 @@ public class ConnectivityService extends IConnectivityManager.Stub @VisibleForTesting void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks, @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) { - underlyingNetworks = underlyingNetworksOrDefault(underlyingNetworks); + underlyingNetworks = underlyingNetworksOrDefault( + agentCaps.getOwnerUid(), underlyingNetworks); int[] transportTypes = agentCaps.getTransportTypes(); int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; @@ -8073,7 +8105,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } NetworkAgentInfo newDefaultAgent = null; if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) { - newDefaultAgent = getDefaultNetwork(); + newDefaultAgent = mDefaultRequest.getSatisfier(); if (newDefaultAgent != null) { intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, newDefaultAgent.networkInfo); @@ -8121,9 +8153,14 @@ public class ConnectivityService extends IConnectivityManager.Stub private Network[] getDefaultNetworks() { ensureRunningOnConnectivityServiceThread(); final ArrayList defaultNetworks = new ArrayList<>(); - final NetworkAgentInfo defaultNetwork = getDefaultNetwork(); + final Set activeNetIds = new ArraySet<>(); + for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { + if (nri.isBeingSatisfied()) { + activeNetIds.add(nri.getSatisfier().network().netId); + } + } 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); } }