Merge changes Id5e5b911,I8301abad,I7262811a,I658e579b,I7d43ef0e
* changes: Expose access UIDs. Send access UIDs to netd Add accessUids to NetworkCapabilities. Clean up restrictions on network agent capabilities Sanitize NetworkCapabilities from agent on the handler thread
This commit is contained in:
commit
4fcb8ad292
8 changed files with 473 additions and 59 deletions
|
|
@ -132,6 +132,7 @@ package android.net {
|
|||
}
|
||||
|
||||
public final class NetworkCapabilities implements android.os.Parcelable {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public java.util.Set<java.lang.Integer> getAccessUids();
|
||||
method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
|
||||
method public boolean hasForbiddenCapability(int);
|
||||
field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
|
||||
|
|
@ -143,6 +144,7 @@ package android.net {
|
|||
}
|
||||
|
||||
public static final class NetworkCapabilities.Builder {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAccessUids(@NonNull java.util.Set<java.lang.Integer>);
|
||||
method @NonNull public android.net.NetworkCapabilities.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
mTransportInfo = null;
|
||||
mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
|
||||
mUids = null;
|
||||
mAccessUids.clear();
|
||||
mAdministratorUids = new int[0];
|
||||
mOwnerUid = Process.INVALID_UID;
|
||||
mSSID = null;
|
||||
|
|
@ -294,6 +295,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
}
|
||||
mSignalStrength = nc.mSignalStrength;
|
||||
mUids = (nc.mUids == null) ? null : new ArraySet<>(nc.mUids);
|
||||
setAccessUids(nc.mAccessUids);
|
||||
setAdministratorUids(nc.getAdministratorUids());
|
||||
mOwnerUid = nc.mOwnerUid;
|
||||
mForbiddenNetworkCapabilities = nc.mForbiddenNetworkCapabilities;
|
||||
|
|
@ -1025,6 +1027,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
final int[] originalAdministratorUids = getAdministratorUids();
|
||||
final TransportInfo originalTransportInfo = getTransportInfo();
|
||||
final Set<Integer> originalSubIds = getSubscriptionIds();
|
||||
final Set<Integer> originalAccessUids = new ArraySet<>(mAccessUids);
|
||||
clearAll();
|
||||
if (0 != (originalCapabilities & (1 << NET_CAPABILITY_NOT_RESTRICTED))) {
|
||||
// If the test network is not restricted, then it is only allowed to declare some
|
||||
|
|
@ -1044,6 +1047,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
mNetworkSpecifier = originalSpecifier;
|
||||
mSignalStrength = originalSignalStrength;
|
||||
mTransportInfo = originalTransportInfo;
|
||||
mAccessUids.addAll(originalAccessUids);
|
||||
|
||||
// Only retain the owner and administrator UIDs if they match the app registering the remote
|
||||
// caller that registered the network.
|
||||
|
|
@ -1808,6 +1812,86 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of UIDs that can always access this network.
|
||||
* <p>
|
||||
* UIDs in this list have access to this network, even if the network doesn't have the
|
||||
* {@link #NET_CAPABILITY_NOT_RESTRICTED} capability and the UID does not hold the
|
||||
* {@link android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS} permission.
|
||||
* This is only useful for restricted networks. For non-restricted networks it has no effect.
|
||||
* <p>
|
||||
* This is disallowed in {@link NetworkRequest}, and can only be set by network agents. Network
|
||||
* agents also have restrictions on how they can set these ; they can only back a public
|
||||
* Android API. As such, Ethernet agents can set this when backing the per-UID access API, and
|
||||
* Telephony can set exactly one UID which has to match the manager app for the associated
|
||||
* subscription. Failure to comply with these rules will see this member cleared.
|
||||
* <p>
|
||||
* This member is never null, but can be empty.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
private final ArraySet<Integer> mAccessUids = new ArraySet<>();
|
||||
|
||||
/**
|
||||
* Set the list of UIDs that can always access this network.
|
||||
* @param uids
|
||||
* @hide
|
||||
*/
|
||||
public void setAccessUids(@NonNull final Set<Integer> uids) {
|
||||
// could happen with nc.set(nc), cheaper than always making a defensive copy
|
||||
if (uids == mAccessUids) return;
|
||||
|
||||
Objects.requireNonNull(uids);
|
||||
mAccessUids.clear();
|
||||
mAccessUids.addAll(uids);
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of UIDs that can always access this network.
|
||||
*
|
||||
* The UIDs in this list can always access this network, even if it is restricted and
|
||||
* the UID doesn't hold the USE_RESTRICTED_NETWORKS permission. This is defined by the
|
||||
* network agent in charge of creating the network.
|
||||
*
|
||||
* The UIDs are only visible to network factories and the system server, since the system
|
||||
* server makes sure to redact them before sending a NetworkCapabilities to a process
|
||||
* that doesn't hold the permission.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
|
||||
public @NonNull Set<Integer> getAccessUids() {
|
||||
return new ArraySet<>(mAccessUids);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
// For internal clients that know what they are doing and need to avoid the performance hit
|
||||
// of the defensive copy.
|
||||
public @NonNull ArraySet<Integer> getAccessUidsNoCopy() {
|
||||
return mAccessUids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether this UID has special permission to access this network, as per mAccessUids.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isAccessUid(int uid) {
|
||||
return mAccessUids.contains(uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether any UID is in the list of access UIDs
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasAccessUids() {
|
||||
return !mAccessUids.isEmpty();
|
||||
}
|
||||
|
||||
private boolean equalsAccessUids(@NonNull NetworkCapabilities other) {
|
||||
return mAccessUids.equals(other.mAccessUids);
|
||||
}
|
||||
|
||||
/**
|
||||
* The SSID of the network, or null if not applicable or unknown.
|
||||
* <p>
|
||||
|
|
@ -1962,6 +2046,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
&& equalsSpecifier(that)
|
||||
&& equalsTransportInfo(that)
|
||||
&& equalsUids(that)
|
||||
&& equalsAccessUids(that)
|
||||
&& equalsSSID(that)
|
||||
&& equalsOwnerUid(that)
|
||||
&& equalsPrivateDnsBroken(that)
|
||||
|
|
@ -1986,15 +2071,16 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
+ mSignalStrength * 29
|
||||
+ mOwnerUid * 31
|
||||
+ Objects.hashCode(mUids) * 37
|
||||
+ Objects.hashCode(mSSID) * 41
|
||||
+ Objects.hashCode(mTransportInfo) * 43
|
||||
+ Objects.hashCode(mPrivateDnsBroken) * 47
|
||||
+ Objects.hashCode(mRequestorUid) * 53
|
||||
+ Objects.hashCode(mRequestorPackageName) * 59
|
||||
+ Arrays.hashCode(mAdministratorUids) * 61
|
||||
+ Objects.hashCode(mSubIds) * 67
|
||||
+ Objects.hashCode(mUnderlyingNetworks) * 71
|
||||
+ mEnterpriseId * 73;
|
||||
+ Objects.hashCode(mAccessUids) * 41
|
||||
+ Objects.hashCode(mSSID) * 43
|
||||
+ Objects.hashCode(mTransportInfo) * 47
|
||||
+ Objects.hashCode(mPrivateDnsBroken) * 53
|
||||
+ Objects.hashCode(mRequestorUid) * 59
|
||||
+ Objects.hashCode(mRequestorPackageName) * 61
|
||||
+ Arrays.hashCode(mAdministratorUids) * 67
|
||||
+ Objects.hashCode(mSubIds) * 71
|
||||
+ Objects.hashCode(mUnderlyingNetworks) * 73
|
||||
+ mEnterpriseId * 79;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2022,6 +2108,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
dest.writeParcelable((Parcelable) mTransportInfo, flags);
|
||||
dest.writeInt(mSignalStrength);
|
||||
writeParcelableArraySet(dest, mUids, flags);
|
||||
dest.writeIntArray(CollectionUtils.toIntArray(mAccessUids));
|
||||
dest.writeString(mSSID);
|
||||
dest.writeBoolean(mPrivateDnsBroken);
|
||||
dest.writeIntArray(getAdministratorUids());
|
||||
|
|
@ -2034,7 +2121,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
|
||||
new Creator<NetworkCapabilities>() {
|
||||
new Creator<>() {
|
||||
@Override
|
||||
public NetworkCapabilities createFromParcel(Parcel in) {
|
||||
NetworkCapabilities netCap = new NetworkCapabilities();
|
||||
|
|
@ -2048,6 +2135,11 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
netCap.mTransportInfo = in.readParcelable(null);
|
||||
netCap.mSignalStrength = in.readInt();
|
||||
netCap.mUids = readParcelableArraySet(in, null /* ClassLoader, null for default */);
|
||||
final int[] accessUids = in.createIntArray();
|
||||
netCap.mAccessUids.ensureCapacity(accessUids.length);
|
||||
for (int uid : accessUids) {
|
||||
netCap.mAccessUids.add(uid);
|
||||
}
|
||||
netCap.mSSID = in.readString();
|
||||
netCap.mPrivateDnsBroken = in.readBoolean();
|
||||
netCap.setAdministratorUids(in.createIntArray());
|
||||
|
|
@ -2124,6 +2216,11 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
sb.append(" Uids: <").append(mUids).append(">");
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAccessUids()) {
|
||||
sb.append(" AccessUids: <").append(mAccessUids).append(">");
|
||||
}
|
||||
|
||||
if (mOwnerUid != Process.INVALID_UID) {
|
||||
sb.append(" OwnerUid: ").append(mOwnerUid);
|
||||
}
|
||||
|
|
@ -2300,7 +2397,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
|
||||
private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) {
|
||||
if (!isValidCapability(capability)) {
|
||||
throw new IllegalArgumentException("NetworkCapability " + capability + "out of range");
|
||||
throw new IllegalArgumentException("NetworkCapability " + capability + " out of range");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2908,6 +3005,44 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a list of UIDs that can always access this network
|
||||
* <p>
|
||||
* Provide a list of UIDs that can access this network even if the network doesn't have the
|
||||
* {@link #NET_CAPABILITY_NOT_RESTRICTED} capability and the UID does not hold the
|
||||
* {@link android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS} permission.
|
||||
* <p>
|
||||
* This is disallowed in {@link NetworkRequest}, and can only be set by
|
||||
* {@link NetworkAgent}s, who hold the
|
||||
* {@link android.Manifest.permission.NETWORK_FACTORY} permission.
|
||||
* Network agents also have restrictions on how they can set these ; they can only back
|
||||
* a public Android API. As such, Ethernet agents can set this when backing the per-UID
|
||||
* access API, and Telephony can set exactly one UID which has to match the manager app for
|
||||
* the associated subscription. Failure to comply with these rules will see this member
|
||||
* cleared.
|
||||
* <p>
|
||||
* These UIDs are only visible to network factories and the system server, since the system
|
||||
* server makes sure to redact them before sending a {@link NetworkCapabilities} instance
|
||||
* to a process that doesn't hold the {@link android.Manifest.permission.NETWORK_FACTORY}
|
||||
* permission.
|
||||
* <p>
|
||||
* This list cannot be null, but it can be empty to mean that no UID without the
|
||||
* {@link android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS} permission
|
||||
* gets to access this network.
|
||||
*
|
||||
* @param uids the list of UIDs that can always access this network
|
||||
* @return this builder
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
|
||||
public Builder setAccessUids(@NonNull Set<Integer> uids) {
|
||||
Objects.requireNonNull(uids);
|
||||
mCaps.setAccessUids(uids);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the underlying networks of this network.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -439,8 +439,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
* Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID.
|
||||
* The default request uses PREFERENCE_ORDER_DEFAULT.
|
||||
*/
|
||||
// Bound for the lowest valid preference order.
|
||||
static final int PREFERENCE_ORDER_LOWEST = 999;
|
||||
// Used when sending to netd to code for "no order".
|
||||
static final int PREFERENCE_ORDER_NONE = 0;
|
||||
// Order for requests that don't code for a per-app preference. As it is
|
||||
|
|
@ -448,11 +446,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
// PREFERENCE_ORDER_NONE when sending to netd.
|
||||
@VisibleForTesting
|
||||
static final int PREFERENCE_ORDER_INVALID = Integer.MAX_VALUE;
|
||||
// Order for the default internet request. Since this must always have the
|
||||
// lowest priority, its value is larger than the largest acceptable value. As
|
||||
// it is out of the valid range, the corresponding order should be
|
||||
// PREFERENCE_ORDER_NONE when sending to netd.
|
||||
static final int PREFERENCE_ORDER_DEFAULT = 1000;
|
||||
// As a security feature, VPNs have the top priority.
|
||||
static final int PREFERENCE_ORDER_VPN = 0; // Netd supports only 0 for VPN.
|
||||
// Order of per-app OEM preference. See {@link #setOemNetworkPreference}.
|
||||
|
|
@ -467,6 +460,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
// See {@link ConnectivitySettingsManager#setMobileDataPreferredUids}
|
||||
@VisibleForTesting
|
||||
static final int PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED = 30;
|
||||
// Preference order that signifies the network shouldn't be set as a default network for
|
||||
// the UIDs, only give them access to it. TODO : replace this with a boolean
|
||||
// in NativeUidRangeConfig
|
||||
@VisibleForTesting
|
||||
static final int PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT = 999;
|
||||
// Bound for the lowest valid preference order.
|
||||
static final int PREFERENCE_ORDER_LOWEST = 999;
|
||||
|
||||
/**
|
||||
* used internally to clear a wakelock when transitioning
|
||||
|
|
@ -2099,6 +2099,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
newNc.setAdministratorUids(new int[0]);
|
||||
if (!checkAnyPermissionOf(
|
||||
callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
|
||||
newNc.setAccessUids(new ArraySet<>());
|
||||
newNc.setSubscriptionIds(Collections.emptySet());
|
||||
}
|
||||
|
||||
|
|
@ -3348,18 +3349,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
|
||||
switch (msg.what) {
|
||||
case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
|
||||
NetworkCapabilities networkCapabilities = (NetworkCapabilities) arg.second;
|
||||
if (networkCapabilities.hasConnectivityManagedCapability()) {
|
||||
Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
|
||||
}
|
||||
if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
|
||||
// Make sure the original object is not mutated. NetworkAgent normally
|
||||
// makes a copy of the capabilities when sending the message through
|
||||
// the Messenger, but if this ever changes, not making a defensive copy
|
||||
// here will give attack vectors to clients using this code path.
|
||||
networkCapabilities = new NetworkCapabilities(networkCapabilities);
|
||||
networkCapabilities.restrictCapabilitiesForTestNetwork(nai.creatorUid);
|
||||
}
|
||||
final NetworkCapabilities networkCapabilities = new NetworkCapabilities(
|
||||
(NetworkCapabilities) arg.second);
|
||||
processCapabilitiesFromAgent(nai, networkCapabilities);
|
||||
updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
|
||||
break;
|
||||
|
|
@ -6220,6 +6211,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
if (nc.isPrivateDnsBroken()) {
|
||||
throw new IllegalArgumentException("Can't request broken private DNS");
|
||||
}
|
||||
if (nc.hasAccessUids()) {
|
||||
throw new IllegalArgumentException("Can't request access UIDs");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
|
||||
|
|
@ -6454,9 +6448,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
ensureRequestableCapabilities(networkCapabilities);
|
||||
ensureSufficientPermissionsForRequest(networkCapabilities,
|
||||
Binder.getCallingPid(), callingUid, callingPackageName);
|
||||
ensureValidNetworkSpecifier(networkCapabilities);
|
||||
restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
|
||||
callingUid, callingPackageName);
|
||||
ensureValid(networkCapabilities);
|
||||
|
||||
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
|
||||
nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
|
||||
NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
|
||||
|
|
@ -6976,28 +6971,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
|
||||
NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId,
|
||||
int uid) {
|
||||
if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
|
||||
// Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
|
||||
// the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
|
||||
// sees capabilities that may be malicious, which might prevent mistakes in the future.
|
||||
networkCapabilities = new NetworkCapabilities(networkCapabilities);
|
||||
networkCapabilities.restrictCapabilitiesForTestNetwork(uid);
|
||||
}
|
||||
|
||||
LinkProperties lp = new LinkProperties(linkProperties);
|
||||
|
||||
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
||||
// At this point the capabilities/properties are untrusted and unverified, e.g. checks that
|
||||
// the capabilities' access UID comply with security limitations. They will be sanitized
|
||||
// as the NAI registration finishes, in handleRegisterNetworkAgent(). This is
|
||||
// because some of the checks must happen on the handler thread.
|
||||
final NetworkAgentInfo nai = new NetworkAgentInfo(na,
|
||||
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
|
||||
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo),
|
||||
linkProperties, networkCapabilities,
|
||||
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
|
||||
this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs,
|
||||
mQosCallbackTracker, mDeps);
|
||||
|
||||
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
|
||||
processCapabilitiesFromAgent(nai, nc);
|
||||
nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
|
||||
processLinkPropertiesFromAgent(nai, nai.linkProperties);
|
||||
|
||||
final String extraInfo = networkInfo.getExtraInfo();
|
||||
final String name = TextUtils.isEmpty(extraInfo)
|
||||
? nai.networkCapabilities.getSsid() : extraInfo;
|
||||
|
|
@ -7012,8 +6997,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
}
|
||||
|
||||
private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
|
||||
if (VDBG) log("Network Monitor created for " + nai);
|
||||
// nai.nc and nai.lp are the same object that was passed by the network agent if the agent
|
||||
// lives in the same process as this code (e.g. wifi), so make sure this code doesn't
|
||||
// mutate their object
|
||||
final NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
|
||||
final LinkProperties lp = new LinkProperties(nai.linkProperties);
|
||||
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
|
||||
processCapabilitiesFromAgent(nai, nc);
|
||||
nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
|
||||
processLinkPropertiesFromAgent(nai, lp);
|
||||
nai.linkProperties = lp;
|
||||
|
||||
nai.onNetworkMonitorCreated(networkMonitor);
|
||||
if (VDBG) log("Got NetworkAgent Messenger");
|
||||
|
||||
mNetworkAgentInfos.add(nai);
|
||||
synchronized (mNetworkForNetId) {
|
||||
mNetworkForNetId.put(nai.network.getNetId(), nai);
|
||||
|
|
@ -7024,6 +7021,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
|
||||
nai.notifyRegistered();
|
||||
NetworkInfo networkInfo = nai.networkInfo;
|
||||
updateNetworkInfo(nai, networkInfo);
|
||||
|
|
@ -7471,9 +7469,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
* Stores into |nai| any data coming from the agent that might also be written to the network's
|
||||
* NetworkCapabilities by ConnectivityService itself. This ensures that the data provided by the
|
||||
* agent is not lost when updateCapabilities is called.
|
||||
* This method should never alter the agent's NetworkCapabilities, only store data in |nai|.
|
||||
*/
|
||||
private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) {
|
||||
if (nc.hasConnectivityManagedCapability()) {
|
||||
Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
|
||||
}
|
||||
// Note: resetting the owner UID before storing the agent capabilities in NAI means that if
|
||||
// the agent attempts to change the owner UID, then nai.declaredCapabilities will not
|
||||
// actually be the same as the capabilities sent by the agent. Still, it is safer to reset
|
||||
|
|
@ -7484,6 +7484,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
nc.setOwnerUid(nai.networkCapabilities.getOwnerUid());
|
||||
}
|
||||
nai.declaredCapabilities = new NetworkCapabilities(nc);
|
||||
NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent(nc, nai.creatorUid);
|
||||
}
|
||||
|
||||
/** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */
|
||||
|
|
@ -7748,6 +7749,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
return stableRanges;
|
||||
}
|
||||
|
||||
private static UidRangeParcel[] intsToUidRangeStableParcels(
|
||||
final @NonNull ArraySet<Integer> uids) {
|
||||
final UidRangeParcel[] stableRanges = new UidRangeParcel[uids.size()];
|
||||
int index = 0;
|
||||
for (int uid : uids) {
|
||||
stableRanges[index] = new UidRangeParcel(uid, uid);
|
||||
index++;
|
||||
}
|
||||
return stableRanges;
|
||||
}
|
||||
|
||||
private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) {
|
||||
final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
|
||||
for (int i = 0; i < ranges.length; i++) {
|
||||
|
|
@ -7818,8 +7830,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
}
|
||||
}
|
||||
|
||||
private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
|
||||
NetworkCapabilities newNc) {
|
||||
private void updateUids(@NonNull NetworkAgentInfo nai, @Nullable NetworkCapabilities prevNc,
|
||||
@Nullable NetworkCapabilities newNc) {
|
||||
updateVpnUids(nai, prevNc, newNc);
|
||||
updateAccessUids(nai, prevNc, newNc);
|
||||
}
|
||||
|
||||
private void updateVpnUids(@NonNull NetworkAgentInfo nai, @Nullable NetworkCapabilities prevNc,
|
||||
@Nullable NetworkCapabilities newNc) {
|
||||
Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges();
|
||||
Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges();
|
||||
if (null == prevRanges) prevRanges = new ArraySet<>();
|
||||
|
|
@ -7878,6 +7896,46 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
}
|
||||
}
|
||||
|
||||
private void updateAccessUids(@NonNull NetworkAgentInfo nai,
|
||||
@Nullable NetworkCapabilities prevNc, @Nullable NetworkCapabilities newNc) {
|
||||
// In almost all cases both NC code for empty access UIDs. return as fast as possible.
|
||||
final boolean prevEmpty = null == prevNc || prevNc.getAccessUidsNoCopy().isEmpty();
|
||||
final boolean newEmpty = null == newNc || newNc.getAccessUidsNoCopy().isEmpty();
|
||||
if (prevEmpty && newEmpty) return;
|
||||
|
||||
final ArraySet<Integer> prevUids =
|
||||
null == prevNc ? new ArraySet<>() : prevNc.getAccessUidsNoCopy();
|
||||
final ArraySet<Integer> newUids =
|
||||
null == newNc ? new ArraySet<>() : newNc.getAccessUidsNoCopy();
|
||||
|
||||
if (prevUids.equals(newUids)) return;
|
||||
|
||||
// This implementation is very simple and vastly faster for sets of Integers than
|
||||
// CompareOrUpdateResult, which is tuned for sets that need to be compared based on
|
||||
// a key computed from the value and has storage for that.
|
||||
final ArraySet<Integer> toRemove = new ArraySet<>(prevUids);
|
||||
final ArraySet<Integer> toAdd = new ArraySet<>(newUids);
|
||||
toRemove.removeAll(newUids);
|
||||
toAdd.removeAll(prevUids);
|
||||
|
||||
try {
|
||||
if (!toAdd.isEmpty()) {
|
||||
mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
|
||||
nai.network.netId,
|
||||
intsToUidRangeStableParcels(toAdd),
|
||||
PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT));
|
||||
}
|
||||
if (!toRemove.isEmpty()) {
|
||||
mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
|
||||
nai.network.netId,
|
||||
intsToUidRangeStableParcels(toRemove),
|
||||
PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT));
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Netd died. This usually causes a runtime restart anyway.
|
||||
}
|
||||
}
|
||||
|
||||
public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
|
||||
ensureRunningOnConnectivityServiceThread();
|
||||
|
||||
|
|
@ -9844,7 +9902,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
android.Manifest.permission.NETWORK_STACK);
|
||||
final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
|
||||
if (!nc.hasTransport(TRANSPORT_TEST)) {
|
||||
throw new SecurityException("Data Stall simluation is only possible for test networks");
|
||||
throw new SecurityException("Data Stall simulation is only possible for test networks");
|
||||
}
|
||||
|
||||
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
package com.android.server.connectivity;
|
||||
|
||||
import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||
import static android.net.NetworkCapabilities.transportNamesOf;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
|
@ -52,6 +54,7 @@ import android.os.RemoteException;
|
|||
import android.os.SystemClock;
|
||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||
import android.telephony.data.NrQosSessionAttributes;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.SparseArray;
|
||||
|
|
@ -1188,6 +1191,38 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
|
|||
return mConnectivityReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the NC from network agents don't contain stuff they shouldn't.
|
||||
*
|
||||
* @param nc the capabilities to sanitize
|
||||
* @param creatorUid the UID of the process creating this network agent
|
||||
*/
|
||||
public static void restrictCapabilitiesFromNetworkAgent(@NonNull final NetworkCapabilities nc,
|
||||
final int creatorUid) {
|
||||
if (nc.hasTransport(TRANSPORT_TEST)) {
|
||||
nc.restrictCapabilitiesForTestNetwork(creatorUid);
|
||||
}
|
||||
if (!areAccessUidsAcceptableFromNetworkAgent(nc)) {
|
||||
nc.setAccessUids(new ArraySet<>());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areAccessUidsAcceptableFromNetworkAgent(
|
||||
@NonNull final NetworkCapabilities nc) {
|
||||
// NCs without access UIDs are fine.
|
||||
if (!nc.hasAccessUids()) return true;
|
||||
|
||||
// On a non-restricted network, access UIDs make no sense
|
||||
if (nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) return false;
|
||||
|
||||
// If this network has TRANSPORT_TEST, then the caller can do whatever they want to
|
||||
// access UIDs
|
||||
if (nc.hasTransport(TRANSPORT_TEST)) return true;
|
||||
|
||||
// TODO : accept more supported cases
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Print shorter members first and only print the boolean variable which value is true
|
||||
// to improve readability.
|
||||
public String toString() {
|
||||
|
|
|
|||
|
|
@ -308,6 +308,48 @@ public class NetworkCapabilitiesTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test @IgnoreUpTo(SC_V2)
|
||||
public void testSetAccessUids() {
|
||||
final NetworkCapabilities nc = new NetworkCapabilities();
|
||||
assertThrows(NullPointerException.class, () -> nc.setAccessUids(null));
|
||||
assertFalse(nc.hasAccessUids());
|
||||
assertFalse(nc.isAccessUid(0));
|
||||
assertFalse(nc.isAccessUid(1000));
|
||||
assertEquals(0, nc.getAccessUids().size());
|
||||
nc.setAccessUids(new ArraySet<>());
|
||||
assertFalse(nc.hasAccessUids());
|
||||
assertFalse(nc.isAccessUid(0));
|
||||
assertFalse(nc.isAccessUid(1000));
|
||||
assertEquals(0, nc.getAccessUids().size());
|
||||
|
||||
final ArraySet<Integer> uids = new ArraySet<>();
|
||||
uids.add(200);
|
||||
uids.add(250);
|
||||
uids.add(-1);
|
||||
uids.add(Integer.MAX_VALUE);
|
||||
nc.setAccessUids(uids);
|
||||
assertNotEquals(nc, new NetworkCapabilities());
|
||||
assertTrue(nc.hasAccessUids());
|
||||
|
||||
final List<Integer> includedList = List.of(-2, 0, 199, 700, 901, 1000, Integer.MIN_VALUE);
|
||||
final List<Integer> excludedList = List.of(-1, 200, 250, Integer.MAX_VALUE);
|
||||
for (final int uid : includedList) {
|
||||
assertFalse(nc.isAccessUid(uid));
|
||||
}
|
||||
for (final int uid : excludedList) {
|
||||
assertTrue(nc.isAccessUid(uid));
|
||||
}
|
||||
|
||||
final Set<Integer> outUids = nc.getAccessUids();
|
||||
assertEquals(4, outUids.size());
|
||||
for (final int uid : includedList) {
|
||||
assertFalse(outUids.contains(uid));
|
||||
}
|
||||
for (final int uid : excludedList) {
|
||||
assertTrue(outUids.contains(uid));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelNetworkCapabilities() {
|
||||
final Set<Range<Integer>> uids = new ArraySet<>();
|
||||
|
|
@ -318,6 +360,10 @@ public class NetworkCapabilitiesTest {
|
|||
.addCapability(NET_CAPABILITY_EIMS)
|
||||
.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||
if (isAtLeastS()) {
|
||||
final ArraySet<Integer> accessUids = new ArraySet<>();
|
||||
accessUids.add(4);
|
||||
accessUids.add(9);
|
||||
netCap.setAccessUids(accessUids);
|
||||
netCap.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2));
|
||||
netCap.setUids(uids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import android.net.INetworkAgent
|
|||
import android.net.INetworkAgentRegistry
|
||||
import android.net.InetAddresses
|
||||
import android.net.IpPrefix
|
||||
import android.net.KeepalivePacketData
|
||||
import android.net.LinkAddress
|
||||
import android.net.LinkProperties
|
||||
import android.net.NattKeepalivePacketData
|
||||
|
|
@ -42,6 +41,7 @@ import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED
|
|||
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
|
||||
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
||||
import android.net.NetworkCapabilities.TRANSPORT_VPN
|
||||
import android.net.NetworkInfo
|
||||
|
|
@ -53,7 +53,6 @@ import android.net.RouteInfo
|
|||
import android.net.QosCallback
|
||||
import android.net.QosCallbackException
|
||||
import android.net.QosCallback.QosCallbackRegistrationException
|
||||
import android.net.QosFilter
|
||||
import android.net.QosSession
|
||||
import android.net.QosSessionAttributes
|
||||
import android.net.QosSocketInfo
|
||||
|
|
@ -67,7 +66,6 @@ import android.net.cts.NetworkAgentTest.TestableQosCallback.CallbackEntry.OnQosS
|
|||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.os.SystemClock
|
||||
import android.telephony.TelephonyManager
|
||||
|
|
@ -82,6 +80,8 @@ import com.android.testutils.CompatUtil
|
|||
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
||||
import com.android.testutils.DevSdkIgnoreRunner
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.Available
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.Losing
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.Lost
|
||||
import com.android.testutils.TestableNetworkAgent
|
||||
|
|
@ -100,7 +100,6 @@ import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnUnregisterQosC
|
|||
import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnValidationStatus
|
||||
import com.android.testutils.TestableNetworkCallback
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
import org.junit.Assume.assumeFalse
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
|
@ -462,6 +461,36 @@ class NetworkAgentTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun ncWithAccessUids(vararg uids: Int) = NetworkCapabilities.Builder()
|
||||
.addTransportType(TRANSPORT_TEST)
|
||||
.setAccessUids(uids.toSet()).build()
|
||||
|
||||
@Test
|
||||
fun testRejectedUpdates() {
|
||||
val callback = TestableNetworkCallback()
|
||||
// will be cleaned up in tearDown
|
||||
registerNetworkCallback(makeTestNetworkRequest(), callback)
|
||||
val agent = createNetworkAgent(initialNc = ncWithAccessUids(200))
|
||||
agent.register()
|
||||
agent.markConnected()
|
||||
|
||||
// Make sure the UIDs have been ignored.
|
||||
callback.expectCallback<Available>(agent.network!!)
|
||||
callback.expectCapabilitiesThat(agent.network!!) {
|
||||
it.accessUids.isEmpty() && !it.hasCapability(NET_CAPABILITY_VALIDATED)
|
||||
}
|
||||
callback.expectCallback<LinkPropertiesChanged>(agent.network!!)
|
||||
callback.expectCallback<BlockedStatus>(agent.network!!)
|
||||
callback.expectCapabilitiesThat(agent.network!!) {
|
||||
it.accessUids.isEmpty() && it.hasCapability(NET_CAPABILITY_VALIDATED)
|
||||
}
|
||||
callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||
|
||||
// Make sure that the UIDs are also ignored upon update
|
||||
agent.sendNetworkCapabilities(ncWithAccessUids(200, 300))
|
||||
callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSendScore() {
|
||||
// This test will create two networks and check that the one with the stronger
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
|
|||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
|
||||
|
|
@ -109,6 +110,9 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
|
|||
case TRANSPORT_WIFI_AWARE:
|
||||
mScore = new NetworkScore.Builder().setLegacyInt(20).build();
|
||||
break;
|
||||
case TRANSPORT_TEST:
|
||||
mScore = new NetworkScore.Builder().build();
|
||||
break;
|
||||
case TRANSPORT_VPN:
|
||||
mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN);
|
||||
// VPNs deduce the SUSPENDED capability from their underlying networks and there
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import static android.Manifest.permission.CREATE_USERS;
|
|||
import static android.Manifest.permission.DUMP;
|
||||
import static android.Manifest.permission.GET_INTENT_SENDER_INTENT;
|
||||
import static android.Manifest.permission.LOCAL_MAC_ADDRESS;
|
||||
import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
|
||||
import static android.Manifest.permission.NETWORK_FACTORY;
|
||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||
import static android.Manifest.permission.NETWORK_STACK;
|
||||
|
|
@ -108,6 +109,7 @@ import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
|||
import static android.net.NetworkCapabilities.REDACT_NONE;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
|
||||
|
|
@ -1490,6 +1492,10 @@ public class ConnectivityServiceTest {
|
|||
r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new);
|
||||
}
|
||||
|
||||
private UidRangeParcel[] intToUidRangeStableParcels(final @NonNull Set<Integer> ranges) {
|
||||
return ranges.stream().map(r -> new UidRangeParcel(r, r)).toArray(UidRangeParcel[]::new);
|
||||
}
|
||||
|
||||
private VpnManagerService makeVpnManagerService() {
|
||||
final VpnManagerService.Dependencies deps = new VpnManagerService.Dependencies() {
|
||||
public int getCallingUid() {
|
||||
|
|
@ -3813,20 +3819,50 @@ public class ConnectivityServiceTest {
|
|||
public void testNoMutableNetworkRequests() throws Exception {
|
||||
final PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
||||
mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE);
|
||||
NetworkRequest request1 = new NetworkRequest.Builder()
|
||||
final NetworkRequest request1 = new NetworkRequest.Builder()
|
||||
.addCapability(NET_CAPABILITY_VALIDATED)
|
||||
.build();
|
||||
NetworkRequest request2 = new NetworkRequest.Builder()
|
||||
final NetworkRequest request2 = new NetworkRequest.Builder()
|
||||
.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL)
|
||||
.build();
|
||||
|
||||
Class<IllegalArgumentException> expected = IllegalArgumentException.class;
|
||||
final Class<IllegalArgumentException> expected = IllegalArgumentException.class;
|
||||
assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback()));
|
||||
assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent));
|
||||
assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback()));
|
||||
assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoAccessUidsInNetworkRequests() throws Exception {
|
||||
final PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
||||
mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE);
|
||||
final NetworkRequest r = new NetworkRequest.Builder().build();
|
||||
final ArraySet<Integer> accessUids = new ArraySet<>();
|
||||
accessUids.add(6);
|
||||
accessUids.add(9);
|
||||
r.networkCapabilities.setAccessUids(accessUids);
|
||||
|
||||
final Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
|
||||
final NetworkCallback cb = new NetworkCallback();
|
||||
|
||||
final Class<IllegalArgumentException> expected = IllegalArgumentException.class;
|
||||
assertThrows(expected, () -> mCm.requestNetwork(r, cb));
|
||||
assertThrows(expected, () -> mCm.requestNetwork(r, pendingIntent));
|
||||
assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb));
|
||||
assertThrows(expected, () -> mCm.registerNetworkCallback(r, cb, handler));
|
||||
assertThrows(expected, () -> mCm.registerNetworkCallback(r, pendingIntent));
|
||||
assertThrows(expected, () -> mCm.registerBestMatchingNetworkCallback(r, cb, handler));
|
||||
|
||||
// Make sure that resetting the access UIDs to the empty set will allow calling
|
||||
// requestNetwork and registerNetworkCallback.
|
||||
r.networkCapabilities.setAccessUids(Collections.emptySet());
|
||||
mCm.requestNetwork(r, cb);
|
||||
mCm.unregisterNetworkCallback(cb);
|
||||
mCm.registerNetworkCallback(r, cb);
|
||||
mCm.unregisterNetworkCallback(cb);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMMSonWiFi() throws Exception {
|
||||
// Test bringing up cellular without MMS NetworkRequest gets reaped
|
||||
|
|
@ -14571,6 +14607,75 @@ public class ConnectivityServiceTest {
|
|||
() -> mCm.registerNetworkCallback(getRequestWithSubIds(), new NetworkCallback()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessUids() throws Exception {
|
||||
final int preferenceOrder =
|
||||
ConnectivityService.PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT;
|
||||
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED);
|
||||
mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED);
|
||||
final TestNetworkCallback cb = new TestNetworkCallback();
|
||||
mCm.requestNetwork(new NetworkRequest.Builder()
|
||||
.clearCapabilities()
|
||||
.addTransportType(TRANSPORT_TEST)
|
||||
.build(),
|
||||
cb);
|
||||
|
||||
final ArraySet<Integer> uids = new ArraySet<>();
|
||||
uids.add(200);
|
||||
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
|
||||
.addTransportType(TRANSPORT_TEST)
|
||||
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||
.setAccessUids(uids)
|
||||
.build();
|
||||
final TestNetworkAgentWrapper agent = new TestNetworkAgentWrapper(TRANSPORT_TEST,
|
||||
new LinkProperties(), nc);
|
||||
agent.connect(true);
|
||||
cb.expectAvailableThenValidatedCallbacks(agent);
|
||||
|
||||
final InOrder inOrder = inOrder(mMockNetd);
|
||||
final NativeUidRangeConfig uids200Parcel = new NativeUidRangeConfig(
|
||||
agent.getNetwork().getNetId(),
|
||||
intToUidRangeStableParcels(uids),
|
||||
preferenceOrder);
|
||||
inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids200Parcel);
|
||||
|
||||
uids.add(300);
|
||||
uids.add(400);
|
||||
nc.setAccessUids(uids);
|
||||
agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */);
|
||||
cb.expectCapabilitiesThat(agent, caps -> caps.getAccessUids().equals(uids));
|
||||
|
||||
uids.remove(200);
|
||||
final NativeUidRangeConfig uids300400Parcel = new NativeUidRangeConfig(
|
||||
agent.getNetwork().getNetId(),
|
||||
intToUidRangeStableParcels(uids),
|
||||
preferenceOrder);
|
||||
inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids300400Parcel);
|
||||
|
||||
nc.setAccessUids(uids);
|
||||
agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */);
|
||||
cb.expectCapabilitiesThat(agent, caps -> caps.getAccessUids().equals(uids));
|
||||
inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids200Parcel);
|
||||
|
||||
uids.clear();
|
||||
uids.add(600);
|
||||
nc.setAccessUids(uids);
|
||||
agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */);
|
||||
cb.expectCapabilitiesThat(agent, caps -> caps.getAccessUids().equals(uids));
|
||||
final NativeUidRangeConfig uids600Parcel = new NativeUidRangeConfig(
|
||||
agent.getNetwork().getNetId(),
|
||||
intToUidRangeStableParcels(uids),
|
||||
preferenceOrder);
|
||||
inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(uids600Parcel);
|
||||
inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids300400Parcel);
|
||||
|
||||
uids.clear();
|
||||
nc.setAccessUids(uids);
|
||||
agent.setNetworkCapabilities(nc, true /* sendToConnectivityService */);
|
||||
cb.expectCapabilitiesThat(agent, caps -> caps.getAccessUids().isEmpty());
|
||||
inOrder.verify(mMockNetd, times(1)).networkRemoveUidRangesParcel(uids600Parcel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate request counts are counted accurately on setProfileNetworkPreference on set/replace.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue