Resolve merge conflicts of d15f09adf7 to master
Test: this is the exact code these changes were meant to give
without conflict had the auto-merger not squashed them
together before it tried to merge them. It was tested on
master in this state.
Change-Id: I5cbde17fb6016e5e6b5d0b04c8f41858d708ef4a
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package android.net;
|
package android.net;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager.PacketKeepalive;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -26,7 +27,6 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.android.internal.util.AsyncChannel;
|
import com.android.internal.util.AsyncChannel;
|
||||||
import com.android.internal.util.Protocol;
|
import com.android.internal.util.Protocol;
|
||||||
import android.net.ConnectivityManager.PacketKeepalive;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -100,20 +100,6 @@ public abstract class NetworkAgent extends Handler {
|
|||||||
*/
|
*/
|
||||||
public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
|
public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
|
||||||
|
|
||||||
/**
|
|
||||||
* Sent by the NetworkAgent to ConnectivityService to add new UID ranges
|
|
||||||
* to be forced into this Network. For VPNs only.
|
|
||||||
* obj = UidRange[] to forward
|
|
||||||
*/
|
|
||||||
public static final int EVENT_UID_RANGES_ADDED = BASE + 5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sent by the NetworkAgent to ConnectivityService to remove UID ranges
|
|
||||||
* from being forced into this Network. For VPNs only.
|
|
||||||
* obj = UidRange[] to stop forwarding
|
|
||||||
*/
|
|
||||||
public static final int EVENT_UID_RANGES_REMOVED = BASE + 6;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sent by ConnectivityService to the NetworkAgent to inform the agent of the
|
* Sent by ConnectivityService to the NetworkAgent to inform the agent of the
|
||||||
* networks status - whether we could use the network or could not, due to
|
* networks status - whether we could use the network or could not, due to
|
||||||
@@ -389,22 +375,6 @@ public abstract class NetworkAgent extends Handler {
|
|||||||
queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
|
queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by the VPN code when it wants to add ranges of UIDs to be routed
|
|
||||||
* through the VPN network.
|
|
||||||
*/
|
|
||||||
public void addUidRanges(UidRange[] ranges) {
|
|
||||||
queueOrSendMessage(EVENT_UID_RANGES_ADDED, ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by the VPN code when it wants to remove ranges of UIDs from being routed
|
|
||||||
* through the VPN network.
|
|
||||||
*/
|
|
||||||
public void removeUidRanges(UidRange[] ranges) {
|
|
||||||
queueOrSendMessage(EVENT_UID_RANGES_REMOVED, ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the bearer to indicate this network was manually selected by the user.
|
* Called by the bearer to indicate this network was manually selected by the user.
|
||||||
* This should be called before the NetworkInfo is marked CONNECTED so that this
|
* This should be called before the NetworkInfo is marked CONNECTED so that this
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
|
|||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -29,6 +30,7 @@ import com.android.internal.util.Preconditions;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,6 +49,7 @@ import java.util.StringJoiner;
|
|||||||
*/
|
*/
|
||||||
public final class NetworkCapabilities implements Parcelable {
|
public final class NetworkCapabilities implements Parcelable {
|
||||||
private static final String TAG = "NetworkCapabilities";
|
private static final String TAG = "NetworkCapabilities";
|
||||||
|
private static final int INVALID_UID = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
@@ -64,6 +67,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
||||||
mNetworkSpecifier = nc.mNetworkSpecifier;
|
mNetworkSpecifier = nc.mNetworkSpecifier;
|
||||||
mSignalStrength = nc.mSignalStrength;
|
mSignalStrength = nc.mSignalStrength;
|
||||||
|
mUids = nc.mUids;
|
||||||
|
mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +82,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
|
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
|
||||||
mNetworkSpecifier = null;
|
mNetworkSpecifier = null;
|
||||||
mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
|
mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
|
||||||
|
mUids = null;
|
||||||
|
mEstablishingVpnAppUid = INVALID_UID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -618,6 +625,29 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
return (nc.mTransportTypes == this.mTransportTypes);
|
return (nc.mTransportTypes == this.mTransportTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UID of the app that manages this network, or INVALID_UID if none/unknown.
|
||||||
|
*
|
||||||
|
* This field keeps track of the UID of the app that created this network and is in charge
|
||||||
|
* of managing it. In the practice, it is used to store the UID of VPN apps so it is named
|
||||||
|
* accordingly, but it may be renamed if other mechanisms are offered for third party apps
|
||||||
|
* to create networks.
|
||||||
|
*
|
||||||
|
* Because this field is only used in the services side (and to avoid apps being able to
|
||||||
|
* set this to whatever they want), this field is not parcelled and will not be conserved
|
||||||
|
* across the IPC boundary.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
private int mEstablishingVpnAppUid = INVALID_UID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the UID of the managing app.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setEstablishingVpnAppUid(final int uid) {
|
||||||
|
mEstablishingVpnAppUid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value indicating that link bandwidth is unspecified.
|
* Value indicating that link bandwidth is unspecified.
|
||||||
* @hide
|
* @hide
|
||||||
@@ -836,6 +866,174 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
return this.mSignalStrength == nc.mSignalStrength;
|
return this.mSignalStrength == nc.mSignalStrength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of UIDs this network applies to. No restriction if null.
|
||||||
|
* <p>
|
||||||
|
* This is typically (and at this time, only) used by VPN. This network is only available to
|
||||||
|
* the UIDs in this list, and it is their default network. Apps in this list that wish to
|
||||||
|
* bypass the VPN can do so iff the VPN app allows them to or if they are privileged. If this
|
||||||
|
* member is null, then the network is not restricted by app UID. If it's an empty list, then
|
||||||
|
* it means nobody can use it.
|
||||||
|
* As a special exception, the app managing this network (as identified by its UID stored in
|
||||||
|
* mEstablishingVpnAppUid) can always see this network. This is embodied by a special check in
|
||||||
|
* satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong>
|
||||||
|
* to the app that manages it as determined by #appliesToUid.
|
||||||
|
* <p>
|
||||||
|
* Please note that in principle a single app can be associated with multiple UIDs because
|
||||||
|
* each app will have a different UID when it's run as a different (macro-)user. A single
|
||||||
|
* macro user can only have a single active VPN app at any given time however.
|
||||||
|
* <p>
|
||||||
|
* Also please be aware this class does not try to enforce any normalization on this. Callers
|
||||||
|
* can only alter the UIDs by setting them wholesale : this class does not provide any utility
|
||||||
|
* to add or remove individual UIDs or ranges. If callers have any normalization needs on
|
||||||
|
* their own (like requiring sortedness or no overlap) they need to enforce it
|
||||||
|
* themselves. Some of the internal methods also assume this is normalized as in no adjacent
|
||||||
|
* or overlapping ranges are present.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
private Set<UidRange> mUids = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to set the UIDs this network applies to to a single UID.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public NetworkCapabilities setSingleUid(int uid) {
|
||||||
|
final ArraySet<UidRange> identity = new ArraySet<>(1);
|
||||||
|
identity.add(new UidRange(uid, uid));
|
||||||
|
setUids(identity);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of UIDs this network applies to.
|
||||||
|
* This makes a copy of the set so that callers can't modify it after the call.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public NetworkCapabilities setUids(Set<UidRange> uids) {
|
||||||
|
if (null == uids) {
|
||||||
|
mUids = null;
|
||||||
|
} else {
|
||||||
|
mUids = new ArraySet<>(uids);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of UIDs this network applies to.
|
||||||
|
* This returns a copy of the set so that callers can't modify the original object.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public Set<UidRange> getUids() {
|
||||||
|
return null == mUids ? null : new ArraySet<>(mUids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether this network applies to this UID.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean appliesToUid(int uid) {
|
||||||
|
if (null == mUids) return true;
|
||||||
|
for (UidRange range : mUids) {
|
||||||
|
if (range.contains(uid)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the set of UIDs that this network applies to is the same of the passed set of UIDs.
|
||||||
|
* <p>
|
||||||
|
* This test only checks whether equal range objects are in both sets. It will
|
||||||
|
* return false if the ranges are not exactly the same, even if the covered UIDs
|
||||||
|
* are for an equivalent result.
|
||||||
|
* <p>
|
||||||
|
* Note that this method is not very optimized, which is fine as long as it's not used very
|
||||||
|
* often.
|
||||||
|
* <p>
|
||||||
|
* nc is assumed nonnull.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean equalsUids(NetworkCapabilities nc) {
|
||||||
|
Set<UidRange> comparedUids = nc.mUids;
|
||||||
|
if (null == comparedUids) return null == mUids;
|
||||||
|
if (null == mUids) return false;
|
||||||
|
// Make a copy so it can be mutated to check that all ranges in mUids
|
||||||
|
// also are in uids.
|
||||||
|
final Set<UidRange> uids = new ArraySet<>(mUids);
|
||||||
|
for (UidRange range : comparedUids) {
|
||||||
|
if (!uids.contains(range)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uids.remove(range);
|
||||||
|
}
|
||||||
|
return uids.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the passed NetworkCapabilities satisfies the UIDs this capabilities require.
|
||||||
|
*
|
||||||
|
* This method is called on the NetworkCapabilities embedded in a request with the
|
||||||
|
* capabilities of an available network. It checks whether all the UIDs from this listen
|
||||||
|
* (representing the UIDs that must have access to the network) are satisfied by the UIDs
|
||||||
|
* in the passed nc (representing the UIDs that this network is available to).
|
||||||
|
* <p>
|
||||||
|
* As a special exception, the UID that created the passed network (as represented by its
|
||||||
|
* mEstablishingVpnAppUid field) always satisfies a NetworkRequest requiring it (of LISTEN
|
||||||
|
* or REQUEST types alike), even if the network does not apply to it. That is so a VPN app
|
||||||
|
* can see its own network when it listens for it.
|
||||||
|
* <p>
|
||||||
|
* nc is assumed nonnull. Else, NPE.
|
||||||
|
* @see #appliesToUid
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean satisfiedByUids(NetworkCapabilities nc) {
|
||||||
|
if (null == nc.mUids) return true; // The network satisfies everything.
|
||||||
|
if (null == mUids) return false; // Not everything allowed but requires everything
|
||||||
|
for (UidRange requiredRange : mUids) {
|
||||||
|
if (requiredRange.contains(nc.mEstablishingVpnAppUid)) return true;
|
||||||
|
if (!nc.appliesToUidRange(requiredRange)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this network applies to the passed ranges.
|
||||||
|
* This assumes that to apply, the passed range has to be entirely contained
|
||||||
|
* within one of the ranges this network applies to. If the ranges are not normalized,
|
||||||
|
* this method may return false even though all required UIDs are covered because no
|
||||||
|
* single range contained them all.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean appliesToUidRange(UidRange requiredRange) {
|
||||||
|
if (null == mUids) return true;
|
||||||
|
for (UidRange uidRange : mUids) {
|
||||||
|
if (uidRange.containsRange(requiredRange)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine the UIDs this network currently applies to with the UIDs the passed
|
||||||
|
* NetworkCapabilities apply to.
|
||||||
|
* nc is assumed nonnull.
|
||||||
|
*/
|
||||||
|
private void combineUids(NetworkCapabilities nc) {
|
||||||
|
if (null == nc.mUids || null == mUids) {
|
||||||
|
mUids = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mUids.addAll(nc.mUids);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
|
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
|
||||||
* @hide
|
* @hide
|
||||||
@@ -846,6 +1044,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
combineLinkBandwidths(nc);
|
combineLinkBandwidths(nc);
|
||||||
combineSpecifiers(nc);
|
combineSpecifiers(nc);
|
||||||
combineSignalStrength(nc);
|
combineSignalStrength(nc);
|
||||||
|
combineUids(nc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -858,12 +1057,13 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
|
private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
|
||||||
return (nc != null &&
|
return (nc != null
|
||||||
satisfiedByNetCapabilities(nc, onlyImmutable) &&
|
&& satisfiedByNetCapabilities(nc, onlyImmutable)
|
||||||
satisfiedByTransportTypes(nc) &&
|
&& satisfiedByTransportTypes(nc)
|
||||||
(onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
|
&& (onlyImmutable || satisfiedByLinkBandwidths(nc))
|
||||||
satisfiedBySpecifier(nc) &&
|
&& satisfiedBySpecifier(nc)
|
||||||
(onlyImmutable || satisfiedBySignalStrength(nc)));
|
&& (onlyImmutable || satisfiedBySignalStrength(nc))
|
||||||
|
&& (onlyImmutable || satisfiedByUids(nc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -944,24 +1144,26 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
|
if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
|
||||||
NetworkCapabilities that = (NetworkCapabilities)obj;
|
NetworkCapabilities that = (NetworkCapabilities) obj;
|
||||||
return (equalsNetCapabilities(that) &&
|
return (equalsNetCapabilities(that)
|
||||||
equalsTransportTypes(that) &&
|
&& equalsTransportTypes(that)
|
||||||
equalsLinkBandwidths(that) &&
|
&& equalsLinkBandwidths(that)
|
||||||
equalsSignalStrength(that) &&
|
&& equalsSignalStrength(that)
|
||||||
equalsSpecifier(that));
|
&& equalsSpecifier(that)
|
||||||
|
&& equalsUids(that));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
|
return ((int) (mNetworkCapabilities & 0xFFFFFFFF)
|
||||||
((int)(mNetworkCapabilities >> 32) * 3) +
|
+ ((int) (mNetworkCapabilities >> 32) * 3)
|
||||||
((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
|
+ ((int) (mTransportTypes & 0xFFFFFFFF) * 5)
|
||||||
((int)(mTransportTypes >> 32) * 7) +
|
+ ((int) (mTransportTypes >> 32) * 7)
|
||||||
(mLinkUpBandwidthKbps * 11) +
|
+ (mLinkUpBandwidthKbps * 11)
|
||||||
(mLinkDownBandwidthKbps * 13) +
|
+ (mLinkDownBandwidthKbps * 13)
|
||||||
Objects.hashCode(mNetworkSpecifier) * 17 +
|
+ Objects.hashCode(mNetworkSpecifier) * 17
|
||||||
(mSignalStrength * 19));
|
+ (mSignalStrength * 19)
|
||||||
|
+ Objects.hashCode(mUids) * 23);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -976,6 +1178,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
dest.writeInt(mLinkDownBandwidthKbps);
|
dest.writeInt(mLinkDownBandwidthKbps);
|
||||||
dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
|
dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
|
||||||
dest.writeInt(mSignalStrength);
|
dest.writeInt(mSignalStrength);
|
||||||
|
dest.writeArraySet(new ArraySet<>(mUids));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<NetworkCapabilities> CREATOR =
|
public static final Creator<NetworkCapabilities> CREATOR =
|
||||||
@@ -990,6 +1193,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
netCap.mLinkDownBandwidthKbps = in.readInt();
|
netCap.mLinkDownBandwidthKbps = in.readInt();
|
||||||
netCap.mNetworkSpecifier = in.readParcelable(null);
|
netCap.mNetworkSpecifier = in.readParcelable(null);
|
||||||
netCap.mSignalStrength = in.readInt();
|
netCap.mSignalStrength = in.readInt();
|
||||||
|
netCap.mUids = (ArraySet<UidRange>) in.readArraySet(
|
||||||
|
null /* ClassLoader, null for default */);
|
||||||
return netCap;
|
return netCap;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@@ -1022,7 +1227,12 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
|
|
||||||
String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
|
String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
|
||||||
|
|
||||||
return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
|
String uids = (null != mUids ? " Uids: <" + mUids + ">" : "");
|
||||||
|
|
||||||
|
String establishingAppUid = " EstablishingAppUid: " + mEstablishingVpnAppUid;
|
||||||
|
|
||||||
|
return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength
|
||||||
|
+ uids + establishingAppUid + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
|||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
|
|
||||||
@@ -106,6 +107,7 @@ import android.security.Credentials;
|
|||||||
import android.security.KeyStore;
|
import android.security.KeyStore;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.LocalLog;
|
import android.util.LocalLog;
|
||||||
import android.util.LocalLog.ReadOnlyLocalLog;
|
import android.util.LocalLog.ReadOnlyLocalLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -176,6 +178,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
@@ -733,12 +736,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mSystemProperties = getSystemProperties();
|
mSystemProperties = getSystemProperties();
|
||||||
|
|
||||||
mMetricsLog = logger;
|
mMetricsLog = logger;
|
||||||
mDefaultRequest = createInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
|
mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
|
||||||
NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
|
NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
|
||||||
mNetworkRequests.put(mDefaultRequest, defaultNRI);
|
mNetworkRequests.put(mDefaultRequest, defaultNRI);
|
||||||
mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
|
mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
|
||||||
|
|
||||||
mDefaultMobileDataRequest = createInternetRequestForTransport(
|
mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
|
||||||
NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
|
NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
|
||||||
|
|
||||||
mHandlerThread = new HandlerThread("ConnectivityServiceThread");
|
mHandlerThread = new HandlerThread("ConnectivityServiceThread");
|
||||||
@@ -903,7 +906,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
deps);
|
deps);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetworkRequest createInternetRequestForTransport(
|
private NetworkRequest createDefaultInternetRequestForTransport(
|
||||||
int transportType, NetworkRequest.Type type) {
|
int transportType, NetworkRequest.Type type) {
|
||||||
NetworkCapabilities netCap = new NetworkCapabilities();
|
NetworkCapabilities netCap = new NetworkCapabilities();
|
||||||
netCap.addCapability(NET_CAPABILITY_INTERNET);
|
netCap.addCapability(NET_CAPABILITY_INTERNET);
|
||||||
@@ -1281,7 +1284,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
for (Network network : networks) {
|
for (Network network : networks) {
|
||||||
nai = getNetworkAgentInfoForNetwork(network);
|
nai = getNetworkAgentInfoForNetwork(network);
|
||||||
nc = getNetworkCapabilitiesInternal(nai);
|
nc = getNetworkCapabilitiesInternal(nai);
|
||||||
|
// nc is a copy of the capabilities in nai, so it's fine to mutate it
|
||||||
|
// TODO : don't remove the UIDs when communicating with processes
|
||||||
|
// that have the NETWORK_SETTINGS permission.
|
||||||
if (nc != null) {
|
if (nc != null) {
|
||||||
|
nc.setSingleUid(userId);
|
||||||
result.put(network, nc);
|
result.put(network, nc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2079,24 +2086,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
if (score != null) updateNetworkScore(nai, score.intValue());
|
if (score != null) updateNetworkScore(nai, score.intValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NetworkAgent.EVENT_UID_RANGES_ADDED: {
|
|
||||||
try {
|
|
||||||
mNetd.addVpnUidRanges(nai.network.netId, (UidRange[])msg.obj);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Never crash!
|
|
||||||
loge("Exception in addVpnUidRanges: " + e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NetworkAgent.EVENT_UID_RANGES_REMOVED: {
|
|
||||||
try {
|
|
||||||
mNetd.removeVpnUidRanges(nai.network.netId, (UidRange[])msg.obj);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Never crash!
|
|
||||||
loge("Exception in removeVpnUidRanges: " + e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
|
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
|
||||||
if (nai.everConnected && !nai.networkMisc.explicitlySelected) {
|
if (nai.everConnected && !nai.networkMisc.explicitlySelected) {
|
||||||
loge("ERROR: already-connected network explicitly selected.");
|
loge("ERROR: already-connected network explicitly selected.");
|
||||||
@@ -4235,6 +4224,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// the system default network.
|
// the system default network.
|
||||||
if (type == NetworkRequest.Type.TRACK_DEFAULT) {
|
if (type == NetworkRequest.Type.TRACK_DEFAULT) {
|
||||||
networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities);
|
networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities);
|
||||||
|
networkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN);
|
||||||
enforceAccessPermission();
|
enforceAccessPermission();
|
||||||
} else {
|
} else {
|
||||||
networkCapabilities = new NetworkCapabilities(networkCapabilities);
|
networkCapabilities = new NetworkCapabilities(networkCapabilities);
|
||||||
@@ -4245,6 +4235,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
enforceMeteredApnPolicy(networkCapabilities);
|
enforceMeteredApnPolicy(networkCapabilities);
|
||||||
}
|
}
|
||||||
ensureRequestableCapabilities(networkCapabilities);
|
ensureRequestableCapabilities(networkCapabilities);
|
||||||
|
// Set the UID range for this request to the single UID of the requester.
|
||||||
|
// This will overwrite any allowed UIDs in the requested capabilities. Though there
|
||||||
|
// are no visible methods to set the UIDs, an app could use reflection to try and get
|
||||||
|
// networks for other apps so it's essential that the UIDs are overwritten.
|
||||||
|
// TODO : don't forcefully set the UID when communicating with processes
|
||||||
|
// that have the NETWORK_SETTINGS permission.
|
||||||
|
networkCapabilities.setSingleUid(Binder.getCallingUid());
|
||||||
|
|
||||||
if (timeoutMs < 0) {
|
if (timeoutMs < 0) {
|
||||||
throw new IllegalArgumentException("Bad timeout specified");
|
throw new IllegalArgumentException("Bad timeout specified");
|
||||||
@@ -4318,6 +4315,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
enforceMeteredApnPolicy(networkCapabilities);
|
enforceMeteredApnPolicy(networkCapabilities);
|
||||||
ensureRequestableCapabilities(networkCapabilities);
|
ensureRequestableCapabilities(networkCapabilities);
|
||||||
ensureValidNetworkSpecifier(networkCapabilities);
|
ensureValidNetworkSpecifier(networkCapabilities);
|
||||||
|
// TODO : don't forcefully set the UID when communicating with processes
|
||||||
|
// that have the NETWORK_SETTINGS permission.
|
||||||
|
networkCapabilities.setSingleUid(Binder.getCallingUid());
|
||||||
|
|
||||||
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
|
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
|
||||||
nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
|
nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
|
||||||
@@ -4371,6 +4371,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
||||||
|
// TODO : don't forcefully set the UIDs when communicating with processes
|
||||||
|
// that have the NETWORK_SETTINGS permission.
|
||||||
|
nc.setSingleUid(Binder.getCallingUid());
|
||||||
if (!ConnectivityManager.checkChangePermission(mContext)) {
|
if (!ConnectivityManager.checkChangePermission(mContext)) {
|
||||||
// Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
|
// Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
|
||||||
// make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
|
// make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
|
||||||
@@ -4399,8 +4402,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
ensureValidNetworkSpecifier(networkCapabilities);
|
ensureValidNetworkSpecifier(networkCapabilities);
|
||||||
|
|
||||||
NetworkRequest networkRequest = new NetworkRequest(
|
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
||||||
new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(),
|
// TODO : don't forcefully set the UIDs when communicating with processes
|
||||||
|
// that have the NETWORK_SETTINGS permission.
|
||||||
|
nc.setSingleUid(Binder.getCallingUid());
|
||||||
|
|
||||||
|
NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
|
||||||
NetworkRequest.Type.LISTEN);
|
NetworkRequest.Type.LISTEN);
|
||||||
NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
|
NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
|
||||||
if (VDBG) log("pendingListenForNetwork for " + nri);
|
if (VDBG) log("pendingListenForNetwork for " + nri);
|
||||||
@@ -4543,6 +4550,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
NetworkInfo networkInfo = na.networkInfo;
|
NetworkInfo networkInfo = na.networkInfo;
|
||||||
na.networkInfo = null;
|
na.networkInfo = null;
|
||||||
updateNetworkInfo(na, networkInfo);
|
updateNetworkInfo(na, networkInfo);
|
||||||
|
updateUids(na, null, na.networkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp) {
|
private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp) {
|
||||||
@@ -4791,6 +4799,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
nai.networkCapabilities = newNc;
|
nai.networkCapabilities = newNc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateUids(nai, prevNc, newNc);
|
||||||
|
|
||||||
if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
|
if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
|
||||||
// If the requestable capabilities haven't changed, and the score hasn't changed, then
|
// If the requestable capabilities haven't changed, and the score hasn't changed, then
|
||||||
// the change we're processing can't affect any requests, it can only affect the listens
|
// the change we're processing can't affect any requests, it can only affect the listens
|
||||||
@@ -4827,6 +4837,34 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
|
||||||
|
NetworkCapabilities newNc) {
|
||||||
|
Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
|
||||||
|
Set<UidRange> newRanges = null == newNc ? null : newNc.getUids();
|
||||||
|
if (null == prevRanges) prevRanges = new ArraySet<>();
|
||||||
|
if (null == newRanges) newRanges = new ArraySet<>();
|
||||||
|
final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
|
||||||
|
|
||||||
|
prevRanges.removeAll(newRanges);
|
||||||
|
newRanges.removeAll(prevRangesCopy);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!newRanges.isEmpty()) {
|
||||||
|
final UidRange[] addedRangesArray = new UidRange[newRanges.size()];
|
||||||
|
newRanges.toArray(addedRangesArray);
|
||||||
|
mNetd.addVpnUidRanges(nai.network.netId, addedRangesArray);
|
||||||
|
}
|
||||||
|
if (!prevRanges.isEmpty()) {
|
||||||
|
final UidRange[] removedRangesArray = new UidRange[prevRanges.size()];
|
||||||
|
prevRanges.toArray(removedRangesArray);
|
||||||
|
mNetd.removeVpnUidRanges(nai.network.netId, removedRangesArray);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Never crash!
|
||||||
|
loge("Exception in updateUids: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
|
public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
|
||||||
if (mNetworkForNetId.get(nai.network.netId) != nai) {
|
if (mNetworkForNetId.get(nai.network.netId) != nai) {
|
||||||
// Ignore updates for disconnected networks
|
// Ignore updates for disconnected networks
|
||||||
@@ -4918,7 +4956,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConnectivityManager.CALLBACK_CAP_CHANGED: {
|
case ConnectivityManager.CALLBACK_CAP_CHANGED: {
|
||||||
putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
|
final NetworkCapabilities nc =
|
||||||
|
new NetworkCapabilities(networkAgent.networkCapabilities);
|
||||||
|
// TODO : don't remove the UIDs when communicating with processes
|
||||||
|
// that have the NETWORK_SETTINGS permission.
|
||||||
|
nc.setSingleUid(nri.mUid);
|
||||||
|
putParcelable(bundle, nc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConnectivityManager.CALLBACK_IP_CHANGED: {
|
case ConnectivityManager.CALLBACK_IP_CHANGED: {
|
||||||
@@ -5442,6 +5485,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateUids(networkAgent, networkAgent.networkCapabilities, null);
|
||||||
}
|
}
|
||||||
} else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) ||
|
} else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) ||
|
||||||
state == NetworkInfo.State.SUSPENDED) {
|
state == NetworkInfo.State.SUSPENDED) {
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package com.android.server.connectivity;
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
|
import static android.net.util.NetworkConstants.IPV4_HEADER_MIN_LEN;
|
||||||
|
import static android.net.util.NetworkConstants.UDP_HEADER_LEN;
|
||||||
|
|
||||||
import android.system.OsConstants;
|
import android.system.OsConstants;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkUtils;
|
import android.net.NetworkUtils;
|
||||||
@@ -57,9 +60,6 @@ public class KeepalivePacketData {
|
|||||||
/** Packet data. A raw byte string of packet data, not including the link-layer header. */
|
/** Packet data. A raw byte string of packet data, not including the link-layer header. */
|
||||||
public final byte[] data;
|
public final byte[] data;
|
||||||
|
|
||||||
private static final int IPV4_HEADER_LENGTH = 20;
|
|
||||||
private static final int UDP_HEADER_LENGTH = 8;
|
|
||||||
|
|
||||||
protected KeepalivePacketData(InetAddress srcAddress, int srcPort,
|
protected KeepalivePacketData(InetAddress srcAddress, int srcPort,
|
||||||
InetAddress dstAddress, int dstPort, byte[] data) throws InvalidPacketException {
|
InetAddress dstAddress, int dstPort, byte[] data) throws InvalidPacketException {
|
||||||
this.srcAddress = srcAddress;
|
this.srcAddress = srcAddress;
|
||||||
@@ -111,7 +111,7 @@ public class KeepalivePacketData {
|
|||||||
throw new InvalidPacketException(ERROR_INVALID_PORT);
|
throw new InvalidPacketException(ERROR_INVALID_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
|
int length = IPV4_HEADER_MIN_LEN + UDP_HEADER_LEN + 1;
|
||||||
ByteBuffer buf = ByteBuffer.allocate(length);
|
ByteBuffer buf = ByteBuffer.allocate(length);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
buf.putShort((short) 0x4500); // IP version and TOS
|
buf.putShort((short) 0x4500); // IP version and TOS
|
||||||
@@ -130,7 +130,7 @@ public class KeepalivePacketData {
|
|||||||
buf.putShort((short) 0); // UDP checksum
|
buf.putShort((short) 0); // UDP checksum
|
||||||
buf.put((byte) 0xff); // NAT-T keepalive
|
buf.put((byte) 0xff); // NAT-T keepalive
|
||||||
buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
|
buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
|
||||||
buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH));
|
buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_MIN_LEN));
|
||||||
|
|
||||||
return new KeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
|
return new KeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,14 +223,6 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
|
|
||||||
// This represents the last score received from the NetworkAgent.
|
// This represents the last score received from the NetworkAgent.
|
||||||
private int currentScore;
|
private int currentScore;
|
||||||
// Penalty applied to scores of Networks that have not been validated.
|
|
||||||
private static final int UNVALIDATED_SCORE_PENALTY = 40;
|
|
||||||
|
|
||||||
// Score for explicitly connected network.
|
|
||||||
//
|
|
||||||
// This ensures that a) the explicitly selected network is never trumped by anything else, and
|
|
||||||
// b) the explicitly selected network is never torn down.
|
|
||||||
private static final int MAXIMUM_NETWORK_SCORE = 100;
|
|
||||||
|
|
||||||
// The list of NetworkRequests being satisfied by this Network.
|
// The list of NetworkRequests being satisfied by this Network.
|
||||||
private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
|
private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
|
||||||
@@ -428,12 +420,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
// down an explicitly selected network before the user gets a chance to prefer it when
|
// down an explicitly selected network before the user gets a chance to prefer it when
|
||||||
// a higher-scoring network (e.g., Ethernet) is available.
|
// a higher-scoring network (e.g., Ethernet) is available.
|
||||||
if (networkMisc.explicitlySelected && (networkMisc.acceptUnvalidated || pretendValidated)) {
|
if (networkMisc.explicitlySelected && (networkMisc.acceptUnvalidated || pretendValidated)) {
|
||||||
return MAXIMUM_NETWORK_SCORE;
|
return ConnectivityConstants.MAXIMUM_NETWORK_SCORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int score = currentScore;
|
int score = currentScore;
|
||||||
if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty()) {
|
if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty()) {
|
||||||
score -= UNVALIDATED_SCORE_PENALTY;
|
score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
|
||||||
}
|
}
|
||||||
if (score < 0) score = 0;
|
if (score < 0) score = 0;
|
||||||
return score;
|
return score;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.net.Network;
|
|||||||
import android.net.NetworkUtils;
|
import android.net.NetworkUtils;
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.TrafficStats;
|
import android.net.TrafficStats;
|
||||||
|
import android.net.util.NetworkConstants;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.system.ErrnoException;
|
import android.system.ErrnoException;
|
||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
@@ -421,8 +422,6 @@ public class NetworkDiagnostics {
|
|||||||
private class IcmpCheck extends SimpleSocketCheck implements Runnable {
|
private class IcmpCheck extends SimpleSocketCheck implements Runnable {
|
||||||
private static final int TIMEOUT_SEND = 100;
|
private static final int TIMEOUT_SEND = 100;
|
||||||
private static final int TIMEOUT_RECV = 300;
|
private static final int TIMEOUT_RECV = 300;
|
||||||
private static final int ICMPV4_ECHO_REQUEST = 8;
|
|
||||||
private static final int ICMPV6_ECHO_REQUEST = 128;
|
|
||||||
private static final int PACKET_BUFSIZE = 512;
|
private static final int PACKET_BUFSIZE = 512;
|
||||||
private final int mProtocol;
|
private final int mProtocol;
|
||||||
private final int mIcmpType;
|
private final int mIcmpType;
|
||||||
@@ -432,11 +431,11 @@ public class NetworkDiagnostics {
|
|||||||
|
|
||||||
if (mAddressFamily == AF_INET6) {
|
if (mAddressFamily == AF_INET6) {
|
||||||
mProtocol = IPPROTO_ICMPV6;
|
mProtocol = IPPROTO_ICMPV6;
|
||||||
mIcmpType = ICMPV6_ECHO_REQUEST;
|
mIcmpType = NetworkConstants.ICMPV6_ECHO_REQUEST_TYPE;
|
||||||
mMeasurement.description = "ICMPv6";
|
mMeasurement.description = "ICMPv6";
|
||||||
} else {
|
} else {
|
||||||
mProtocol = IPPROTO_ICMP;
|
mProtocol = IPPROTO_ICMP;
|
||||||
mIcmpType = ICMPV4_ECHO_REQUEST;
|
mIcmpType = NetworkConstants.ICMPV4_ECHO_REQUEST_TYPE;
|
||||||
mMeasurement.description = "ICMPv4";
|
mMeasurement.description = "ICMPv4";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,7 +503,6 @@ public class NetworkDiagnostics {
|
|||||||
private class DnsUdpCheck extends SimpleSocketCheck implements Runnable {
|
private class DnsUdpCheck extends SimpleSocketCheck implements Runnable {
|
||||||
private static final int TIMEOUT_SEND = 100;
|
private static final int TIMEOUT_SEND = 100;
|
||||||
private static final int TIMEOUT_RECV = 500;
|
private static final int TIMEOUT_RECV = 500;
|
||||||
private static final int DNS_SERVER_PORT = 53;
|
|
||||||
private static final int RR_TYPE_A = 1;
|
private static final int RR_TYPE_A = 1;
|
||||||
private static final int RR_TYPE_AAAA = 28;
|
private static final int RR_TYPE_AAAA = 28;
|
||||||
private static final int PACKET_BUFSIZE = 512;
|
private static final int PACKET_BUFSIZE = 512;
|
||||||
@@ -546,7 +544,8 @@ public class NetworkDiagnostics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setupSocket(SOCK_DGRAM, IPPROTO_UDP, TIMEOUT_SEND, TIMEOUT_RECV, DNS_SERVER_PORT);
|
setupSocket(SOCK_DGRAM, IPPROTO_UDP, TIMEOUT_SEND, TIMEOUT_RECV,
|
||||||
|
NetworkConstants.DNS_SERVER_PORT);
|
||||||
} catch (ErrnoException | IOException e) {
|
} catch (ErrnoException | IOException e) {
|
||||||
mMeasurement.recordFailure(e.toString());
|
mMeasurement.recordFailure(e.toString());
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -33,12 +33,15 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@@ -180,4 +183,84 @@ public class NetworkCapabilitiesTest {
|
|||||||
assertEquals(20, NetworkCapabilities
|
assertEquals(20, NetworkCapabilities
|
||||||
.maxBandwidth(10, 20));
|
.maxBandwidth(10, 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetUids() {
|
||||||
|
final NetworkCapabilities netCap = new NetworkCapabilities();
|
||||||
|
final Set<UidRange> uids = new ArraySet<>();
|
||||||
|
uids.add(new UidRange(50, 100));
|
||||||
|
uids.add(new UidRange(3000, 4000));
|
||||||
|
netCap.setUids(uids);
|
||||||
|
assertTrue(netCap.appliesToUid(50));
|
||||||
|
assertTrue(netCap.appliesToUid(80));
|
||||||
|
assertTrue(netCap.appliesToUid(100));
|
||||||
|
assertTrue(netCap.appliesToUid(3000));
|
||||||
|
assertTrue(netCap.appliesToUid(3001));
|
||||||
|
assertFalse(netCap.appliesToUid(10));
|
||||||
|
assertFalse(netCap.appliesToUid(25));
|
||||||
|
assertFalse(netCap.appliesToUid(49));
|
||||||
|
assertFalse(netCap.appliesToUid(101));
|
||||||
|
assertFalse(netCap.appliesToUid(2000));
|
||||||
|
assertFalse(netCap.appliesToUid(100000));
|
||||||
|
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(50, 100)));
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(70, 72)));
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912)));
|
||||||
|
assertFalse(netCap.appliesToUidRange(new UidRange(1, 100)));
|
||||||
|
assertFalse(netCap.appliesToUidRange(new UidRange(49, 100)));
|
||||||
|
assertFalse(netCap.appliesToUidRange(new UidRange(1, 10)));
|
||||||
|
assertFalse(netCap.appliesToUidRange(new UidRange(60, 101)));
|
||||||
|
assertFalse(netCap.appliesToUidRange(new UidRange(60, 3400)));
|
||||||
|
|
||||||
|
NetworkCapabilities netCap2 = new NetworkCapabilities();
|
||||||
|
assertFalse(netCap2.satisfiedByUids(netCap));
|
||||||
|
assertFalse(netCap2.equalsUids(netCap));
|
||||||
|
netCap2.setUids(uids);
|
||||||
|
assertTrue(netCap2.satisfiedByUids(netCap));
|
||||||
|
assertTrue(netCap.equalsUids(netCap2));
|
||||||
|
assertTrue(netCap2.equalsUids(netCap));
|
||||||
|
|
||||||
|
uids.add(new UidRange(600, 700));
|
||||||
|
netCap2.setUids(uids);
|
||||||
|
assertFalse(netCap2.satisfiedByUids(netCap));
|
||||||
|
assertFalse(netCap.appliesToUid(650));
|
||||||
|
assertTrue(netCap2.appliesToUid(650));
|
||||||
|
netCap.combineCapabilities(netCap2);
|
||||||
|
assertTrue(netCap2.satisfiedByUids(netCap));
|
||||||
|
assertTrue(netCap.appliesToUid(650));
|
||||||
|
assertFalse(netCap.appliesToUid(500));
|
||||||
|
|
||||||
|
assertFalse(new NetworkCapabilities().satisfiedByUids(netCap));
|
||||||
|
netCap.combineCapabilities(new NetworkCapabilities());
|
||||||
|
assertTrue(netCap.appliesToUid(500));
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000)));
|
||||||
|
assertFalse(netCap2.appliesToUid(500));
|
||||||
|
assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000)));
|
||||||
|
assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParcelNetworkCapabilities() {
|
||||||
|
final Set<UidRange> uids = new ArraySet<>();
|
||||||
|
uids.add(new UidRange(50, 100));
|
||||||
|
uids.add(new UidRange(3000, 4000));
|
||||||
|
final NetworkCapabilities netCap = new NetworkCapabilities()
|
||||||
|
.addCapability(NET_CAPABILITY_INTERNET)
|
||||||
|
.setUids(uids)
|
||||||
|
.addCapability(NET_CAPABILITY_EIMS)
|
||||||
|
.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||||
|
assertEqualsThroughMarshalling(netCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertEqualsThroughMarshalling(NetworkCapabilities netCap) {
|
||||||
|
Parcel p = Parcel.obtain();
|
||||||
|
netCap.writeToParcel(p, /* flags */ 0);
|
||||||
|
p.setDataPosition(0);
|
||||||
|
byte[] marshalledData = p.marshall();
|
||||||
|
|
||||||
|
p = Parcel.obtain();
|
||||||
|
p.unmarshall(marshalledData, 0, marshalledData.length);
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertEquals(NetworkCapabilities.CREATOR.createFromParcel(p), netCap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
|
|||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
|
||||||
|
|
||||||
@@ -101,6 +102,7 @@ import android.net.NetworkSpecifier;
|
|||||||
import android.net.NetworkUtils;
|
import android.net.NetworkUtils;
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.StringNetworkSpecifier;
|
import android.net.StringNetworkSpecifier;
|
||||||
|
import android.net.UidRange;
|
||||||
import android.net.metrics.IpConnectivityLog;
|
import android.net.metrics.IpConnectivityLog;
|
||||||
import android.net.util.MultinetworkPolicyTracker;
|
import android.net.util.MultinetworkPolicyTracker;
|
||||||
import android.os.ConditionVariable;
|
import android.os.ConditionVariable;
|
||||||
@@ -126,11 +128,13 @@ import com.android.internal.util.ArrayUtils;
|
|||||||
import com.android.internal.util.WakeupMessage;
|
import com.android.internal.util.WakeupMessage;
|
||||||
import com.android.internal.util.test.BroadcastInterceptingContext;
|
import com.android.internal.util.test.BroadcastInterceptingContext;
|
||||||
import com.android.internal.util.test.FakeSettingsProvider;
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
|
import com.android.server.connectivity.ConnectivityConstants;
|
||||||
import com.android.server.connectivity.DefaultNetworkMetrics;
|
import com.android.server.connectivity.DefaultNetworkMetrics;
|
||||||
import com.android.server.connectivity.IpConnectivityMetrics;
|
import com.android.server.connectivity.IpConnectivityMetrics;
|
||||||
import com.android.server.connectivity.MockableSystemProperties;
|
import com.android.server.connectivity.MockableSystemProperties;
|
||||||
import com.android.server.connectivity.NetworkAgentInfo;
|
import com.android.server.connectivity.NetworkAgentInfo;
|
||||||
import com.android.server.connectivity.NetworkMonitor;
|
import com.android.server.connectivity.NetworkMonitor;
|
||||||
|
import com.android.server.connectivity.Vpn;
|
||||||
import com.android.server.net.NetworkPinner;
|
import com.android.server.net.NetworkPinner;
|
||||||
import com.android.server.net.NetworkPolicyManagerInternal;
|
import com.android.server.net.NetworkPolicyManagerInternal;
|
||||||
|
|
||||||
@@ -360,7 +364,7 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
MockNetworkAgent(int transport, LinkProperties linkProperties) {
|
MockNetworkAgent(int transport, LinkProperties linkProperties) {
|
||||||
final int type = transportToLegacyType(transport);
|
final int type = transportToLegacyType(transport);
|
||||||
final String typeName = ConnectivityManager.getNetworkTypeName(type);
|
final String typeName = ConnectivityManager.getNetworkTypeName(transport);
|
||||||
mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
|
mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
|
||||||
mNetworkCapabilities = new NetworkCapabilities();
|
mNetworkCapabilities = new NetworkCapabilities();
|
||||||
mNetworkCapabilities.addTransportType(transport);
|
mNetworkCapabilities.addTransportType(transport);
|
||||||
@@ -377,6 +381,9 @@ public class ConnectivityServiceTest {
|
|||||||
case TRANSPORT_WIFI_AWARE:
|
case TRANSPORT_WIFI_AWARE:
|
||||||
mScore = 20;
|
mScore = 20;
|
||||||
break;
|
break;
|
||||||
|
case TRANSPORT_VPN:
|
||||||
|
mScore = ConnectivityConstants.VPN_DEFAULT_SCORE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("unimplemented network type");
|
throw new UnsupportedOperationException("unimplemented network type");
|
||||||
}
|
}
|
||||||
@@ -438,6 +445,11 @@ public class ConnectivityServiceTest {
|
|||||||
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUids(Set<UidRange> uids) {
|
||||||
|
mNetworkCapabilities.setUids(uids);
|
||||||
|
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
public void setSignalStrength(int signalStrength) {
|
public void setSignalStrength(int signalStrength) {
|
||||||
mNetworkCapabilities.setSignalStrength(signalStrength);
|
mNetworkCapabilities.setSignalStrength(signalStrength);
|
||||||
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
||||||
@@ -1463,6 +1475,11 @@ public class ConnectivityServiceTest {
|
|||||||
return nc;
|
return nc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void expectCapabilitiesLike(Predicate<NetworkCapabilities> fn, MockNetworkAgent agent) {
|
||||||
|
CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent);
|
||||||
|
assertTrue(fn.test((NetworkCapabilities) cbi.arg));
|
||||||
|
}
|
||||||
|
|
||||||
void assertNoCallback() {
|
void assertNoCallback() {
|
||||||
waitForIdle();
|
waitForIdle();
|
||||||
CallbackInfo c = mCallbacks.peek();
|
CallbackInfo c = mCallbacks.peek();
|
||||||
@@ -3625,4 +3642,76 @@ public class ConnectivityServiceTest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnNetworkActive() {
|
||||||
|
final int uid = Process.myUid();
|
||||||
|
|
||||||
|
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
|
||||||
|
final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
|
||||||
|
final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
|
||||||
|
final NetworkRequest genericRequest = new NetworkRequest.Builder().build();
|
||||||
|
final NetworkRequest wifiRequest = new NetworkRequest.Builder()
|
||||||
|
.addTransportType(TRANSPORT_WIFI).build();
|
||||||
|
final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder()
|
||||||
|
.addTransportType(TRANSPORT_VPN).build();
|
||||||
|
mCm.registerNetworkCallback(genericRequest, genericNetworkCallback);
|
||||||
|
mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
|
||||||
|
mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
|
||||||
|
|
||||||
|
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||||
|
mWiFiNetworkAgent.connect(false);
|
||||||
|
|
||||||
|
genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
|
wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
|
vpnNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
// TODO : check callbacks agree with the return value of mCm.getActiveNetwork().
|
||||||
|
// Right now this is not possible because establish() is not adequately instrumented
|
||||||
|
// in this test.
|
||||||
|
|
||||||
|
final MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
|
||||||
|
final ArraySet<UidRange> ranges = new ArraySet<>();
|
||||||
|
ranges.add(new UidRange(uid, uid));
|
||||||
|
vpnNetworkAgent.setUids(ranges);
|
||||||
|
vpnNetworkAgent.connect(false);
|
||||||
|
|
||||||
|
genericNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
|
||||||
|
wifiNetworkCallback.assertNoCallback();
|
||||||
|
vpnNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
|
||||||
|
|
||||||
|
genericNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
|
||||||
|
vpnNetworkCallback.expectCapabilitiesLike(
|
||||||
|
nc -> nc.appliesToUid(uid) && !nc.appliesToUid(uid + 1), vpnNetworkAgent);
|
||||||
|
|
||||||
|
ranges.clear();
|
||||||
|
vpnNetworkAgent.setUids(ranges);
|
||||||
|
|
||||||
|
genericNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
|
||||||
|
wifiNetworkCallback.assertNoCallback();
|
||||||
|
vpnNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
|
||||||
|
|
||||||
|
ranges.add(new UidRange(uid, uid));
|
||||||
|
vpnNetworkAgent.setUids(ranges);
|
||||||
|
|
||||||
|
genericNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent);
|
||||||
|
wifiNetworkCallback.assertNoCallback();
|
||||||
|
vpnNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent);
|
||||||
|
|
||||||
|
mWiFiNetworkAgent.disconnect();
|
||||||
|
|
||||||
|
genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
|
||||||
|
wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
|
||||||
|
vpnNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
vpnNetworkAgent.disconnect();
|
||||||
|
|
||||||
|
genericNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
|
||||||
|
wifiNetworkCallback.assertNoCallback();
|
||||||
|
vpnNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
|
||||||
|
|
||||||
|
mCm.unregisterNetworkCallback(genericNetworkCallback);
|
||||||
|
mCm.unregisterNetworkCallback(wifiNetworkCallback);
|
||||||
|
mCm.unregisterNetworkCallback(vpnNetworkCallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user