Merge "Remove legacy network factories"
diff --git a/framework/src/android/net/NetworkAgent.java b/framework/src/android/net/NetworkAgent.java
index d22d82d..27aa15d 100644
--- a/framework/src/android/net/NetworkAgent.java
+++ b/framework/src/android/net/NetworkAgent.java
@@ -20,6 +20,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -775,7 +776,8 @@
* @param underlyingNetworks the new list of underlying networks.
* @see {@link VpnService.Builder#setUnderlyingNetworks(Network[])}
*/
- public final void setUnderlyingNetworks(@Nullable List<Network> underlyingNetworks) {
+ public final void setUnderlyingNetworks(
+ @SuppressLint("NullableCollection") @Nullable List<Network> underlyingNetworks) {
final ArrayList<Network> underlyingArray = (underlyingNetworks != null)
? new ArrayList<>(underlyingNetworks) : null;
queueOrSendMessage(reg -> reg.sendUnderlyingNetworks(underlyingArray));
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index 8bfa77a..55b2c3c 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -1786,6 +1786,15 @@
return 0;
}
+ private <T extends Parcelable> void writeParcelableArraySet(Parcel in,
+ @Nullable ArraySet<T> val, int flags) {
+ final int size = (val != null) ? val.size() : -1;
+ in.writeInt(size);
+ for (int i = 0; i < size; i++) {
+ in.writeParcelable(val.valueAt(i), flags);
+ }
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mNetworkCapabilities);
@@ -1796,7 +1805,7 @@
dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
dest.writeParcelable((Parcelable) mTransportInfo, flags);
dest.writeInt(mSignalStrength);
- dest.writeArraySet(mUids);
+ writeParcelableArraySet(dest, mUids, flags);
dest.writeString(mSSID);
dest.writeBoolean(mPrivateDnsBroken);
dest.writeIntArray(getAdministratorUids());
@@ -1819,8 +1828,7 @@
netCap.mNetworkSpecifier = in.readParcelable(null);
netCap.mTransportInfo = in.readParcelable(null);
netCap.mSignalStrength = in.readInt();
- netCap.mUids = (ArraySet<UidRange>) in.readArraySet(
- null /* ClassLoader, null for default */);
+ netCap.mUids = readParcelableArraySet(in, null /* ClassLoader, null for default */);
netCap.mSSID = in.readString();
netCap.mPrivateDnsBroken = in.readBoolean();
netCap.setAdministratorUids(in.createIntArray());
@@ -1833,6 +1841,20 @@
public NetworkCapabilities[] newArray(int size) {
return new NetworkCapabilities[size];
}
+
+ private @Nullable <T extends Parcelable> ArraySet<T> readParcelableArraySet(Parcel in,
+ @Nullable ClassLoader loader) {
+ final int size = in.readInt();
+ if (size < 0) {
+ return null;
+ }
+ final ArraySet<T> result = new ArraySet<>(size);
+ for (int i = 0; i < size; i++) {
+ final T value = in.readParcelable(loader);
+ result.append(value);
+ }
+ return result;
+ }
};
@Override
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 181d9c2..6e5ae6e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -222,6 +222,7 @@
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -739,11 +740,11 @@
}
private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
- boolean isFallbackNetwork) {
+ boolean isDefaultNetwork) {
if (DBG) {
log("Sending " + state
+ " broadcast for type " + type + " " + nai.toShortString()
- + " isFallbackNetwork=" + isFallbackNetwork);
+ + " isDefaultNetwork=" + isDefaultNetwork);
}
}
@@ -762,10 +763,10 @@
list.add(nai);
}
- // Send a broadcast if this is the first network of its type or if it's the fallback.
- final boolean isFallbackNetwork = mService.isFallbackNetwork(nai);
- if ((list.size() == 1) || isFallbackNetwork) {
- maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isFallbackNetwork);
+ // Send a broadcast if this is the first network of its type or if it's the default.
+ final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
+ if ((list.size() == 1) || isDefaultNetwork) {
+ maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
}
}
@@ -794,7 +795,7 @@
", sending connected broadcast");
final NetworkAgentInfo replacement = list.get(0);
maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
- mService.isFallbackNetwork(replacement));
+ mService.isDefaultNetwork(replacement));
mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
}
}
@@ -810,14 +811,14 @@
// send out another legacy broadcast - currently only used for suspend/unsuspend
// toggle
public void update(NetworkAgentInfo nai) {
- final boolean isFallback = mService.isFallbackNetwork(nai);
+ final boolean isDefault = mService.isDefaultNetwork(nai);
final DetailedState state = nai.networkInfo.getDetailedState();
for (int type = 0; type < mTypeLists.length; type++) {
final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
final boolean contains = (list != null && list.contains(nai));
final boolean isFirst = contains && (nai == list.get(0));
- if (isFirst || contains && isFallback) {
- maybeLogBroadcast(nai, state, type, isFallback);
+ if (isFirst || contains && isDefault) {
+ maybeLogBroadcast(nai, state, type, isDefault);
mService.sendLegacyNetworkBroadcast(nai, state, type);
}
}
@@ -990,6 +991,15 @@
}
/**
+ * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets
+ * requires CAP_NET_ADMIN, which the unit tests do not have.
+ */
+ public int getConnectionOwnerUid(int protocol, InetSocketAddress local,
+ InetSocketAddress remote) {
+ return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote);
+ }
+
+ /**
* @see MultinetworkPolicyTracker
*/
public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(
@@ -1022,12 +1032,12 @@
mMetricsLog = logger;
mNetworkRanker = new NetworkRanker();
- final NetworkRequest fallbackRequest = createDefaultInternetRequestForTransport(
+ final NetworkRequest defaultInternetRequest = createDefaultInternetRequestForTransport(
-1, NetworkRequest.Type.REQUEST);
- mFallbackRequest = new NetworkRequestInfo(null, fallbackRequest, new Binder());
- mNetworkRequests.put(fallbackRequest, mFallbackRequest);
- mDefaultNetworkRequests.add(mFallbackRequest);
- mNetworkRequestInfoLogs.log("REGISTER " + mFallbackRequest);
+ mDefaultRequest = new NetworkRequestInfo(null, defaultInternetRequest, new Binder());
+ mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
+ mDefaultNetworkRequests.add(mDefaultRequest);
+ mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest);
mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
@@ -1217,6 +1227,14 @@
mDnsManager = new DnsManager(mContext, mDnsResolver);
registerPrivateDnsSettingsCallbacks();
+
+ mNoServiceNetwork = new NetworkAgentInfo(null,
+ new Network(NO_SERVICE_NET_ID),
+ new NetworkInfo(TYPE_NONE, 0, "", ""),
+ new LinkProperties(), new NetworkCapabilities(), 0, mContext,
+ null, new NetworkAgentConfig(), this, null,
+ null, null, 0, INVALID_UID,
+ mQosCallbackTracker);
}
private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
@@ -1366,7 +1384,7 @@
}
private NetworkState getUnfilteredActiveNetworkState(int uid) {
- NetworkAgentInfo nai = getFallbackNetwork();
+ NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
final Network[] networks = getVpnUnderlyingNetworks(uid);
if (networks != null) {
@@ -1499,7 +1517,7 @@
}
}
- NetworkAgentInfo nai = getFallbackNetwork();
+ NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid,
ignoreBlocked)) {
return null;
@@ -1638,21 +1656,28 @@
HashMap<Network, NetworkCapabilities> result = new HashMap<>();
- final NetworkAgentInfo nai = getFallbackNetwork();
- 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(
@@ -1674,9 +1699,7 @@
/**
* 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
*/
@@ -2025,7 +2048,7 @@
// TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allow one
// callback from each caller type. Need to re-factor NetdEventListenerService to allow
// multiple NetworkMonitor registrants.
- if (nai != null && nai.satisfies(mFallbackRequest.mRequests.get(0))) {
+ if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) {
nai.networkMonitor().notifyDnsResponse(returnCode);
}
}
@@ -2119,8 +2142,8 @@
private boolean isUidBlockedByRules(int uid, int uidRules, boolean isNetworkMetered,
boolean isBackgroundRestricted) {
- return NetworkPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
- isNetworkMetered, isBackgroundRestricted);
+ return mPolicyManager.checkUidNetworkingBlocked(uid, uidRules, isNetworkMetered,
+ isBackgroundRestricted);
}
/**
@@ -2582,12 +2605,12 @@
pw.println();
pw.println();
- final NetworkAgentInfo fallbackNai = getFallbackNetwork();
+ final NetworkAgentInfo defaultNai = getDefaultNetwork();
pw.print("Active default network: ");
- if (fallbackNai == null) {
+ if (defaultNai == null) {
pw.println("none");
} else {
- pw.println(fallbackNai.network.getNetId());
+ pw.println(defaultNai.network.getNetId());
}
pw.println();
@@ -2970,7 +2993,7 @@
final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0);
final boolean wasValidated = nai.lastValidated;
- final boolean wasFallback = isFallbackNetwork(nai);
+ final boolean wasDefault = isDefaultNetwork(nai);
if (DBG) {
final String logMsg = !TextUtils.isEmpty(redirectUrl)
@@ -2979,7 +3002,7 @@
log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
}
if (valid != nai.lastValidated) {
- if (wasFallback) {
+ if (wasDefault) {
mMetricsLog.logDefaultNetworkValidity(valid);
}
final int oldScore = nai.getCurrentScore();
@@ -3354,13 +3377,13 @@
loge("Error connecting NetworkAgent");
mNetworkAgentInfos.remove(nai);
if (nai != null) {
- final boolean wasFallback = isFallbackNetwork(nai);
+ final boolean wasDefault = isDefaultNetwork(nai);
synchronized (mNetworkForNetId) {
mNetworkForNetId.remove(nai.network.getNetId());
}
mNetIdManager.releaseNetId(nai.network.getNetId());
// Just in case.
- mLegacyTypeTracker.remove(nai, wasFallback);
+ mLegacyTypeTracker.remove(nai, wasDefault);
}
}
}
@@ -3399,8 +3422,8 @@
nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
null, null);
}
- final boolean wasFallback = isFallbackNetwork(nai);
- if (wasFallback) {
+ final boolean wasDefault = isDefaultNetwork(nai);
+ if (wasDefault) {
mDefaultInetConditionPublished = 0;
// Log default network disconnection before required book-keeping.
// Let rematchAllNetworksAndRequests() below record a new default network event
@@ -3435,17 +3458,20 @@
propagateUnderlyingNetworkCapabilities(nai.network);
// Remove all previously satisfied requests.
for (int i = 0; i < nai.numNetworkRequests(); i++) {
- NetworkRequest request = nai.requestAt(i);
+ final NetworkRequest request = nai.requestAt(i);
final NetworkRequestInfo nri = mNetworkRequests.get(request);
final NetworkAgentInfo currentNetwork = nri.getSatisfier();
if (currentNetwork != null
&& currentNetwork.network.getNetId() == nai.network.getNetId()) {
+ // uid rules for this network will be removed in destroyNativeNetwork(nai).
nri.setSatisfier(null, null);
- sendUpdatedScoreToFactories(request, null);
+ if (request.isRequest()) {
+ sendUpdatedScoreToFactories(request, null);
+ }
- if (mFallbackRequest == nri) {
+ if (mDefaultRequest == nri) {
// TODO : make battery stats aware that since 2013 multiple interfaces may be
- // active at the same time. For now keep calling this with the fallback
+ // active at the same time. For now keep calling this with the default
// network, because while incorrect this is the closest to the old (also
// incorrect) behavior.
mNetworkActivityTracker.updateDataActivityTracking(
@@ -3457,9 +3483,9 @@
}
nai.clearLingerState();
// TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after.
- // Currently, deleting it breaks tests that check for the fallback network disconnecting.
+ // Currently, deleting it breaks tests that check for the default network disconnecting.
// Find out why, fix the rematch code, and delete this.
- mLegacyTypeTracker.remove(nai, wasFallback);
+ mLegacyTypeTracker.remove(nai, wasDefault);
rematchAllNetworksAndRequests();
mLingerMonitor.noteDisconnect(nai);
if (nai.created) {
@@ -3467,10 +3493,9 @@
// (routing rules, DNS, etc).
// This may be slow as it requires a lot of netd shelling out to ip and
// ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
- // after we've rematched networks with requests which should make a potential
- // fallback network the default or requested a new network from the
- // NetworkProviders, so network traffic isn't interrupted for an unnecessarily
- // long time.
+ // after we've rematched networks with requests (which might change the default
+ // network or service a new request from an app), so network traffic isn't interrupted
+ // for an unnecessarily long time.
destroyNativeNetwork(nai);
mDnsManager.removeNetwork(nai.network);
}
@@ -3555,8 +3580,8 @@
}
}
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;
}
@@ -3699,7 +3724,7 @@
if (mNetworkRequests.get(nri.mRequests.get(0)) == null) {
return;
}
- if (nri.getSatisfier() != null) {
+ if (nri.isBeingSatisfied()) {
return;
}
if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) {
@@ -4259,7 +4284,7 @@
@Override
public NetworkRequest getDefaultRequest() {
- return mFallbackRequest.mRequests.get(0);
+ return mDefaultRequest.mRequests.get(0);
}
private class InternalHandler extends Handler {
@@ -4505,7 +4530,7 @@
// revalidate the network and generate a ConnectivityDiagnostics ConnectivityReport event.
final NetworkAgentInfo nai;
if (network == null) {
- nai = getFallbackNetwork();
+ nai = getDefaultNetwork();
} else {
nai = getNetworkAgentInfoForNetwork(network);
}
@@ -4524,7 +4549,7 @@
Network network, int uid, boolean hasConnectivity) {
final NetworkAgentInfo nai;
if (network == null) {
- nai = getFallbackNetwork();
+ nai = getDefaultNetwork();
} else {
nai = getNetworkAgentInfoForNetwork(network);
}
@@ -4837,7 +4862,7 @@
}
synchronized (mVpns) {
throwIfLockdownEnabled();
- mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress);
+ mVpns.get(user).startLegacyVpn(profile, mKeyStore, null /* underlying */, egress);
}
}
@@ -4890,7 +4915,8 @@
// see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
// the underlyingNetworks list.
if (underlyingNetworks == null) {
- final NetworkAgentInfo defaultNai = getFallbackNetwork();
+ final NetworkAgentInfo defaultNai = getDefaultNetworkForUid(
+ nai.networkCapabilities.getOwnerUid());
if (defaultNai != null) {
underlyingNetworks = new Network[] { defaultNai.network };
}
@@ -4941,8 +4967,10 @@
}
}
- private Network[] underlyingNetworksOrDefault(Network[] underlyingNetworks) {
- final Network defaultNetwork = getNetwork(getFallbackNetwork());
+ // TODO This needs to be the default network that applies to the NAI.
+ 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 };
@@ -4955,7 +4983,8 @@
// 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);
}
@@ -5486,9 +5515,8 @@
mActiveRequest = activeRequest;
}
- // The network currently satisfying this request, or null if none. Must only be touched
- // on the handler thread. This only makes sense for network requests and not for listens,
- // as defined by NetworkRequest#isRequest(). For listens, this is always null.
+ // The network currently satisfying this NRI. Only one request in an NRI can have a
+ // satisfier. For non-multilayer requests, only REQUEST-type requests can have a satisfier.
@Nullable
private NetworkAgentInfo mSatisfier;
NetworkAgentInfo getSatisfier() {
@@ -5511,6 +5539,18 @@
final int mUid;
final Messenger messenger;
+ /**
+ * Get the list of UIDs this nri applies to.
+ */
+ @NonNull
+ private Set<UidRange> getUids() {
+ // networkCapabilities.getUids() returns a defensive copy.
+ // multilayer requests will all have the same uids so return the first one.
+ final Set<UidRange> uids = null == mRequests.get(0).networkCapabilities.getUids()
+ ? new ArraySet<>() : mRequests.get(0).networkCapabilities.getUids();
+ return uids;
+ }
+
NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
mRequests = initializeRequests(r);
ensureAllNetworkRequestsHaveType(mRequests);
@@ -5544,6 +5584,13 @@
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;
}
@@ -5569,7 +5616,9 @@
@Override
public String toString() {
- return "uid/pid:" + mUid + "/" + mPid + " " + mRequests
+ return "uid/pid:" + mUid + "/" + mPid + " active request Id: "
+ + (mActiveRequest == null ? null : mActiveRequest.requestId)
+ + " " + mRequests
+ (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
}
}
@@ -6007,11 +6056,31 @@
// The always-on request for an Internet-capable network that apps without a specific default
// fall back to.
@NonNull
- private final NetworkRequestInfo mFallbackRequest;
+ private final NetworkRequestInfo mDefaultRequest;
// Collection of NetworkRequestInfo's used for default networks.
@NonNull
private final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>();
+ private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) {
+ return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri);
+ }
+
+ /**
+ * Determine if an nri is a managed default request that disallows default networking.
+ * @param nri the request to evaluate
+ * @return true if device-default networking is disallowed
+ */
+ private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) {
+ // Check if this nri is a managed default that supports the default network at its
+ // lowest priority request.
+ final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0);
+ final NetworkCapabilities lowestPriorityNetCap =
+ nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities;
+ return isPerAppDefaultRequest(nri)
+ && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities(
+ lowestPriorityNetCap));
+ }
+
// Request used to optionally keep mobile data active even when higher
// priority networks like Wi-Fi are active.
private final NetworkRequest mDefaultMobileDataRequest;
@@ -6023,10 +6092,37 @@
// Request used to optionally keep vehicle internal network always active
private final NetworkRequest mDefaultVehicleRequest;
- // TODO: b/178729499 update this in favor of a method taking in a UID.
- // The NetworkAgentInfo currently satisfying the fallback request, if any.
- private NetworkAgentInfo getFallbackNetwork() {
- return mFallbackRequest.mSatisfier;
+ // TODO replace with INetd.DUMMY_NET_ID when available.
+ private static final int NO_SERVICE_NET_ID = 51;
+ // Sentinel NAI used to direct apps with default networks that should have no connectivity to a
+ // network with no service. This NAI should never be matched against, nor should any public API
+ // ever return the associated network. For this reason, this NAI is not in the list of available
+ // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device
+ // default requests that don't support using the device default network which will ultimately
+ // allow ConnectivityService to use this no-service network when calling makeDefaultForApps().
+ @VisibleForTesting
+ final NetworkAgentInfo mNoServiceNetwork;
+
+ // 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<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
@@ -6043,8 +6139,8 @@
}
@VisibleForTesting
- protected boolean isFallbackNetwork(NetworkAgentInfo nai) {
- return nai == getFallbackNetwork();
+ protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
+ return nai == getDefaultNetwork();
}
// TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent
@@ -6113,8 +6209,6 @@
LinkProperties lp = new LinkProperties(linkProperties);
- // TODO: Instead of passing mFallbackRequest, provide an API to determine whether a Network
- // satisfies mFallbackRequest.
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
final NetworkAgentInfo nai = new NetworkAgentInfo(na,
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
@@ -6191,7 +6285,7 @@
// for (LinkProperties lp : newLp.getStackedLinks()) {
// updateMtu(lp, null);
// }
- if (isFallbackNetwork(networkAgent)) {
+ if (isDefaultNetwork(networkAgent)) {
updateTcpBufferSizes(newLp.getTcpBufferSizes());
}
@@ -6203,7 +6297,7 @@
// updateDnses will fetch the private DNS configuration from DnsManager.
mDnsManager.updatePrivateDnsStatus(netId, newLp);
- if (isFallbackNetwork(networkAgent)) {
+ if (isDefaultNetwork(networkAgent)) {
handleApplyDefaultProxy(newLp.getHttpProxy());
} else {
updateProxy(newLp, oldLp);
@@ -6537,7 +6631,8 @@
@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;
@@ -7181,21 +7276,20 @@
log("Switching to new default network for: " + nri + " using " + newDefaultNetwork);
}
- try {
- // TODO http://b/176191930 update netd calls in follow-up CL for multinetwork changes.
- if (mFallbackRequest != nri) {
- return;
- }
-
- if (null != newDefaultNetwork) {
- mNetd.networkSetDefault(newDefaultNetwork.network.getNetId());
- } else {
- mNetd.networkClearDefault();
- }
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Exception setting default network :" + e);
+ // Fix up the NetworkCapabilities of any networks that have this network as underlying.
+ if (newDefaultNetwork != null) {
+ propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network);
}
+ // Set an app level managed default and return since further processing only applies to the
+ // default network.
+ if (mDefaultRequest != nri) {
+ makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork);
+ return;
+ }
+
+ makeDefaultNetwork(newDefaultNetwork);
+
if (oldDefaultNetwork != null) {
mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
}
@@ -7206,10 +7300,6 @@
updateTcpBufferSizes(null != newDefaultNetwork
? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null);
notifyIfacesChangedForNetworkStats();
- // Fix up the NetworkCapabilities of any networks that have this network as underlying.
- if (newDefaultNetwork != null) {
- propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network);
- }
// Log 0 -> X and Y -> X default network transitions, where X is the new default.
final Network network = (newDefaultNetwork != null) ? newDefaultNetwork.network : null;
@@ -7233,6 +7323,49 @@
prevNetwork, prevScore, prevLp, prevNc);
}
+ private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri,
+ @Nullable final NetworkAgentInfo oldDefaultNetwork,
+ @Nullable final NetworkAgentInfo newDefaultNetwork) {
+ try {
+ if (VDBG) {
+ log("Setting default network for " + nri
+ + " using UIDs " + nri.getUids()
+ + " with old network " + (oldDefaultNetwork != null
+ ? oldDefaultNetwork.network().getNetId() : "null")
+ + " and new network " + (newDefaultNetwork != null
+ ? newDefaultNetwork.network().getNetId() : "null"));
+ }
+ if (nri.getUids().isEmpty()) {
+ throw new IllegalStateException("makeDefaultForApps called without specifying"
+ + " any applications to set as the default." + nri);
+ }
+ if (null != newDefaultNetwork) {
+ mNetd.networkAddUidRanges(
+ newDefaultNetwork.network.getNetId(),
+ toUidRangeStableParcels(nri.getUids()));
+ }
+ if (null != oldDefaultNetwork) {
+ mNetd.networkRemoveUidRanges(
+ oldDefaultNetwork.network.getNetId(),
+ toUidRangeStableParcels(nri.getUids()));
+ }
+ } catch (RemoteException | ServiceSpecificException e) {
+ loge("Exception setting OEM network preference default network :" + e);
+ }
+ }
+
+ private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) {
+ try {
+ if (null != newDefaultNetwork) {
+ mNetd.networkSetDefault(newDefaultNetwork.network.getNetId());
+ } else {
+ mNetd.networkClearDefault();
+ }
+ } catch (RemoteException | ServiceSpecificException e) {
+ loge("Exception setting default network :" + e);
+ }
+ }
+
private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
// For consistency with previous behaviour, send onLost callbacks before onAvailable.
processNewlyLostListenRequests(nai);
@@ -7354,9 +7487,9 @@
@Nullable final NetworkAgentInfo previousSatisfier,
@Nullable final NetworkAgentInfo newSatisfier,
final long now) {
- if (newSatisfier != null) {
+ if (null != newSatisfier && mNoServiceNetwork != newSatisfier) {
if (VDBG) log("rematch for " + newSatisfier.toShortString());
- if (previousSatisfier != null) {
+ if (null != previousSatisfier && mNoServiceNetwork != previousSatisfier) {
if (VDBG || DDBG) {
log(" accepting network in place of " + previousSatisfier.toShortString());
}
@@ -7370,7 +7503,7 @@
Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
+ newRequest);
}
- } else {
+ } else if (null != previousSatisfier) {
if (DBG) {
log("Network " + previousSatisfier.toShortString() + " stopped satisfying"
+ " request " + previousRequest.requestId);
@@ -7421,7 +7554,11 @@
break;
}
}
- if (bestNetwork != nri.mSatisfier) {
+ if (null == bestNetwork && isDefaultBlocked(nri)) {
+ // Remove default networking if disallowed for managed default requests.
+ bestNetwork = mNoServiceNetwork;
+ }
+ if (nri.getSatisfier() != bestNetwork) {
// bestNetwork may be null if no network can satisfy this request.
changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork));
@@ -7581,34 +7718,34 @@
private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
@NonNull final NetworkReassignment changes,
@NonNull final Collection<NetworkAgentInfo> nais) {
- final NetworkReassignment.RequestReassignment fallbackReassignment =
- changes.getReassignment(mFallbackRequest);
- final NetworkAgentInfo oldFallbackNetwork =
- null != fallbackReassignment ? fallbackReassignment.mOldNetwork : null;
- final NetworkAgentInfo newFallbackNetwork =
- null != fallbackReassignment ? fallbackReassignment.mNewNetwork : null;
+ final NetworkReassignment.RequestReassignment reassignmentOfDefault =
+ changes.getReassignment(mDefaultRequest);
+ final NetworkAgentInfo oldDefaultNetwork =
+ null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null;
+ final NetworkAgentInfo newDefaultNetwork =
+ null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null;
- if (oldFallbackNetwork != newFallbackNetwork) {
+ if (oldDefaultNetwork != newDefaultNetwork) {
// Maintain the illusion : since the legacy API only understands one network at a time,
// if the default network changed, apps should see a disconnected broadcast for the
// old default network before they see a connected broadcast for the new one.
- if (oldFallbackNetwork != null) {
- mLegacyTypeTracker.remove(oldFallbackNetwork.networkInfo.getType(),
- oldFallbackNetwork, true);
+ if (oldDefaultNetwork != null) {
+ mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
+ oldDefaultNetwork, true);
}
- if (newFallbackNetwork != null) {
+ if (newDefaultNetwork != null) {
// The new default network can be newly null if and only if the old default
// network doesn't satisfy the default request any more because it lost a
// capability.
- mDefaultInetConditionPublished = newFallbackNetwork.lastValidated ? 100 : 0;
+ mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
mLegacyTypeTracker.add(
- newFallbackNetwork.networkInfo.getType(), newFallbackNetwork);
+ newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
// If the legacy VPN is connected, notifyLockdownVpn may end up sending a broadcast
// to reflect the NetworkInfo of this new network. This broadcast has to be sent
// after the disconnect broadcasts above, but before the broadcasts sent by the
// legacy type tracker below.
// TODO : refactor this, it's too complex
- notifyLockdownVpn(newFallbackNetwork);
+ notifyLockdownVpn(newDefaultNetwork);
}
}
@@ -7643,7 +7780,7 @@
}
// A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
- // because usually there are no NetworkRequests it satisfies (e.g., mFallbackRequest
+ // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
// wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
// newNetwork to the tracker explicitly (it's a no-op if it has already been added).
if (nai.isVPN()) {
@@ -7654,9 +7791,9 @@
private void updateInetCondition(NetworkAgentInfo nai) {
// Don't bother updating until we've graduated to validated at least once.
if (!nai.everValidated) return;
- // For now only update icons for the fallback connection.
+ // For now only update icons for the default connection.
// TODO: Update WiFi and cellular icons separately. b/17237507
- if (!isFallbackNetwork(nai)) return;
+ if (!isDefaultNetwork(nai)) return;
int newInetCondition = nai.lastValidated ? 100 : 0;
// Don't repeat publish.
@@ -7924,8 +8061,8 @@
intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
}
NetworkAgentInfo newDefaultAgent = null;
- if (nai.isSatisfyingRequest(mFallbackRequest.mRequests.get(0).requestId)) {
- newDefaultAgent = getFallbackNetwork();
+ if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) {
+ newDefaultAgent = mDefaultRequest.getSatisfier();
if (newDefaultAgent != null) {
intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
newDefaultAgent.networkInfo);
@@ -7973,9 +8110,14 @@
private Network[] getDefaultNetworks() {
ensureRunningOnConnectivityServiceThread();
final ArrayList<Network> defaultNetworks = new ArrayList<>();
- final NetworkAgentInfo fallbackNetwork = getFallbackNetwork();
+ final Set<Integer> 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 == fallbackNetwork || nai.isVPN())) {
+ if (nai.everConnected && (activeNetIds.contains(nai.network().netId) || nai.isVPN())) {
defaultNetworks.add(nai.network);
}
}
@@ -8025,7 +8167,6 @@
int user = UserHandle.getUserId(mDeps.getCallingUid());
final boolean success;
synchronized (mVpns) {
- throwIfLockdownEnabled();
success = mVpns.get(user).setUnderlyingNetworks(networks);
}
return success;
@@ -8308,7 +8449,7 @@
throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
}
- final int uid = InetDiagMessage.getConnectionOwnerUid(connectionInfo.protocol,
+ final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol,
connectionInfo.local, connectionInfo.remote);
/* Filter out Uids not associated with the VPN. */
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index b618d2b..d83ff83 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -226,9 +226,9 @@
final ProxyInfo defaultProxy = getDefaultProxy();
final ProxyInfo proxyInfo = null != defaultProxy ?
defaultProxy : ProxyInfo.buildDirectProxy("", 0, Collections.emptyList());
- mPacProxyInstaller.setCurrentProxyScriptUrl(proxyInfo);
- if (!shouldSendBroadcast(proxyInfo)) {
+ if (mPacProxyInstaller.setCurrentProxyScriptUrl(proxyInfo)
+ == PacProxyInstaller.DONT_SEND_BROADCAST) {
return;
}
if (DBG) Log.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
@@ -244,13 +244,6 @@
}
}
- private boolean shouldSendBroadcast(ProxyInfo proxy) {
- if (Uri.EMPTY.equals(proxy.getPacFileUrl())) return false;
- if (proxy.getPacFileUrl().equals(proxy.getPacFileUrl())
- && (proxy.getPort() > 0)) return true;
- return true;
- }
-
/**
* Sets the global proxy in memory. Also writes the values to the global settings of the device.
*
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index b0cc7f1..9f48535 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1262,22 +1262,28 @@
}
}
- private void updateUidNetworkingBlocked() {
- doAnswer(i -> NetworkPolicyManagerInternal.isUidNetworkingBlocked(
- i.getArgument(0) /* uid */, mUidRules, i.getArgument(1) /* metered */,
- mRestrictBackground)
+ private void mockUidNetworkingBlocked() {
+ doAnswer(i -> mContext.getSystemService(NetworkPolicyManager.class)
+ .checkUidNetworkingBlocked(i.getArgument(0) /* uid */, mUidRules,
+ i.getArgument(1) /* metered */, mRestrictBackground)
).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean());
+
+ doAnswer(inv -> mContext.getSystemService(NetworkPolicyManager.class)
+ .checkUidNetworkingBlocked(inv.getArgument(0) /* uid */,
+ inv.getArgument(1) /* uidRules */,
+ inv.getArgument(2) /* isNetworkMetered */,
+ inv.getArgument(3) /* isBackgroundRestricted */)
+ ).when(mNetworkPolicyManager).checkUidNetworkingBlocked(
+ anyInt(), anyInt(), anyBoolean(), anyBoolean());
}
private void setUidRulesChanged(int uidRules) throws RemoteException {
mUidRules = uidRules;
- updateUidNetworkingBlocked();
mPolicyListener.onUidRulesChanged(Process.myUid(), mUidRules);
}
private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException {
mRestrictBackground = restrictBackground;
- updateUidNetworkingBlocked();
mPolicyListener.onRestrictBackgroundChanged(mRestrictBackground);
}
@@ -6809,6 +6815,7 @@
.addTransportType(TRANSPORT_CELLULAR)
.build();
mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+ mockUidNetworkingBlocked();
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true);
@@ -6891,6 +6898,7 @@
public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception {
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(defaultCallback);
+ mockUidNetworkingBlocked();
// No Networkcallbacks invoked before any network is active.
setUidRulesChanged(RULE_REJECT_ALL);
@@ -7160,6 +7168,13 @@
when(mKeyStore.get(Credentials.VPN + profileName)).thenReturn(encodedProfile);
}
+ private void establishLegacyLockdownVpn() throws Exception {
+ // The legacy lockdown VPN only supports userId 0.
+ final Set<UidRange> ranges = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ mMockVpn.registerAgent(ranges);
+ mMockVpn.connect(true);
+ }
+
@Test
public void testLegacyLockdownVpn() throws Exception {
mServiceContext.setPermission(
@@ -7254,22 +7269,30 @@
mMockVpn.expectStartLegacyVpnRunner();
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
ExpectedBroadcast b2 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED);
- mMockVpn.establishForMyUid();
+ establishLegacyLockdownVpn();
callback.expectAvailableThenValidatedCallbacks(mMockVpn);
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
+ NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
b1.expectBroadcast();
b2.expectBroadcast();
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
+ assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR));
+ assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI));
+ assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED));
// Switch default network from cell to wifi. Expect VPN to disconnect and reconnect.
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName("wlan0");
wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25"));
wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0"));
- mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp);
+ final NetworkCapabilities wifiNc = new NetworkCapabilities();
+ wifiNc.addTransportType(TRANSPORT_WIFI);
+ wifiNc.addCapability(NET_CAPABILITY_NOT_METERED);
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc);
b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED);
// Wifi is CONNECTING because the VPN isn't up yet.
@@ -7302,16 +7325,20 @@
// The VPN comes up again on wifi.
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED);
- mMockVpn.establishForMyUid();
+ establishLegacyLockdownVpn();
callback.expectAvailableThenValidatedCallbacks(mMockVpn);
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
b1.expectBroadcast();
b2.expectBroadcast();
-
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
+ assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
+ assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI));
+ assertFalse(vpnNc.hasTransport(TRANSPORT_CELLULAR));
+ assertTrue(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED));
// Disconnect cell. Nothing much happens since it's not the default network.
// Whenever LockdownVpnTracker is connected, it will send a connected broadcast any time any
@@ -8355,13 +8382,14 @@
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
throws Exception {
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+ mMockVpn.setVpnType(vpnType);
mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
- mMockVpn.setVpnType(vpnType);
final UnderlyingNetworkInfo underlyingNetworkInfo =
new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<String>());
mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo);
+ when(mDeps.getConnectionOwnerUid(anyInt(), any(), any())).thenReturn(42);
}
private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
@@ -8410,8 +8438,7 @@
final int myUid = Process.myUid();
setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE);
- // TODO: Test the returned UID
- mService.getConnectionOwnerUid(getTestConnectionInfo());
+ assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo()));
}
@Test
@@ -8421,8 +8448,7 @@
mServiceContext.setPermission(
android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED);
- // TODO: Test the returned UID
- mService.getConnectionOwnerUid(getTestConnectionInfo());
+ assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo()));
}
@Test
@@ -8433,8 +8459,7 @@
mServiceContext.setPermission(
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED);
- // TODO: Test the returned UID
- mService.getConnectionOwnerUid(getTestConnectionInfo());
+ assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo()));
}
private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) {
diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
index e590fb7..a10a3c8 100644
--- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -55,7 +55,7 @@
private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_SUPL)
private val mMockService = mock(ConnectivityService::class.java).apply {
- doReturn(false).`when`(this).isFallbackNetwork(any())
+ doReturn(false).`when`(this).isDefaultNetwork(any())
}
private val mTracker = LegacyTypeTracker(mMockService).apply {
supportedTypes.forEach {
@@ -126,11 +126,11 @@
fun testBroadcastOnDisconnect() {
val mobileNai1 = mock(NetworkAgentInfo::class.java)
val mobileNai2 = mock(NetworkAgentInfo::class.java)
- doReturn(false).`when`(mMockService).isFallbackNetwork(mobileNai1)
+ doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai1)
mTracker.add(TYPE_MOBILE, mobileNai1)
verify(mMockService).sendLegacyNetworkBroadcast(mobileNai1, CONNECTED, TYPE_MOBILE)
reset(mMockService)
- doReturn(false).`when`(mMockService).isFallbackNetwork(mobileNai2)
+ doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai2)
mTracker.add(TYPE_MOBILE, mobileNai2)
verify(mMockService, never()).sendLegacyNetworkBroadcast(any(), any(), anyInt())
mTracker.remove(TYPE_MOBILE, mobileNai1, false /* wasDefault */)
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 68aaaed..3a93c5b 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -49,6 +49,7 @@
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -119,6 +120,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -148,6 +150,7 @@
managedProfileA.profileGroupId = primaryUser.id;
}
+ static final Network EGRESS_NETWORK = new Network(101);
static final String EGRESS_IFACE = "wlan0";
static final String TEST_VPN_PKG = "com.testvpn.vpn";
private static final String TEST_VPN_SERVER = "1.2.3.4";
@@ -212,6 +215,8 @@
when(mContext.getPackageName()).thenReturn(TEST_VPN_PKG);
when(mContext.getOpPackageName()).thenReturn(TEST_VPN_PKG);
+ when(mContext.getSystemServiceName(UserManager.class))
+ .thenReturn(Context.USER_SERVICE);
when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
when(mContext.getSystemServiceName(NotificationManager.class))
@@ -953,7 +958,14 @@
}
private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception {
- setMockedUsers(primaryUser);
+ // TODO(b/175883995): once these tests have been updated for the changes to the UserManager
+ // API, remove this ad-hoc setup code and use setMockedUsers(primaryUser) again.
+ // setMockedUsers(primaryUser);
+ final ArrayList<UserInfo> users = new ArrayList<>();
+ users.add(primaryUser);
+ when(mUserManager.getAliveUsers()).thenReturn(users);
+ when(mUserManager.getUserInfo(primaryUser.id)).thenReturn(primaryUser);
+ when(mUserManager.canHaveRestrictedProfile()).thenReturn(false);
// Dummy egress interface
final LinkProperties lp = new LinkProperties();
@@ -963,7 +975,7 @@
InetAddresses.parseNumericAddress("192.0.2.0"), EGRESS_IFACE);
lp.addRoute(defaultRoute);
- vpn.startLegacyVpn(vpnProfile, mKeyStore, lp);
+ vpn.startLegacyVpn(vpnProfile, mKeyStore, EGRESS_NETWORK, lp);
return vpn;
}
@@ -996,14 +1008,12 @@
profile.ipsecIdentifier = "id";
profile.ipsecSecret = "secret";
profile.l2tpSecret = "l2tpsecret";
+
when(mConnectivityManager.getAllNetworks())
.thenReturn(new Network[] { new Network(101) });
+
when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(),
- anyInt(), any(), anyInt())).thenAnswer(invocation -> {
- // The runner has registered an agent and is now ready.
- legacyRunnerReady.open();
- return new Network(102);
- });
+ anyInt(), any(), anyInt())).thenReturn(new Network(102));
final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile);
final TestDeps deps = (TestDeps) vpn.mDeps;
try {
@@ -1019,14 +1029,20 @@
"linkname", "vpn", "refuse-eap", "nodefaultroute", "usepeerdns",
"idle", "1800", "mtu", "1270", "mru", "1270" },
deps.mtpdArgs.get(10, TimeUnit.SECONDS));
+
// Now wait for the runner to be ready before testing for the route.
- legacyRunnerReady.block(10_000);
- // In this test the expected address is always v4 so /32
+ ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class);
+ verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(),
+ lpCaptor.capture(), any(), anyInt(), any(), anyInt());
+
+ // In this test the expected address is always v4 so /32.
+ // Note that the interface needs to be specified because RouteInfo objects stored in
+ // LinkProperties objects always acquire the LinkProperties' interface.
final RouteInfo expectedRoute = new RouteInfo(new IpPrefix(expectedAddr + "/32"),
- RouteInfo.RTN_THROW);
- assertTrue("Routes lack the expected throw route (" + expectedRoute + ") : "
- + vpn.mConfig.routes,
- vpn.mConfig.routes.contains(expectedRoute));
+ null, EGRESS_IFACE, RouteInfo.RTN_THROW);
+ final List<RouteInfo> actualRoutes = lpCaptor.getValue().getRoutes();
+ assertTrue("Expected throw route (" + expectedRoute + ") not found in " + actualRoutes,
+ actualRoutes.contains(expectedRoute));
} finally {
// Now interrupt the thread, unblock the runner and clean up.
vpn.mVpnRunner.exitVpnRunner();
@@ -1082,6 +1098,11 @@
}
@Override
+ public PendingIntent getIntentForStatusPanel(Context context) {
+ return null;
+ }
+
+ @Override
public void sendArgumentsToDaemon(
final String daemon, final LocalSocket socket, final String[] arguments,
final Vpn.RetryScheduler interruptChecker) throws IOException {