Merge changes from topics "vpnmove-getconnectionowneruid", "vpnmove-systemdefaultcallback", "vpnmove-vpntransportinfo"
* changes: Stop using mVpns in getConnectionOwnerUid. Add a VpnTransportInfo object. Add a registerSystemDefaultNetworkCallback method.
This commit is contained in:
79
core/java/android/net/VpnTransportInfo.java
Normal file
79
core/java/android/net/VpnTransportInfo.java
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.net;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import com.android.internal.util.MessageUtils;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public final class VpnTransportInfo implements TransportInfo, Parcelable {
|
||||||
|
private static final SparseArray<String> sTypeToString =
|
||||||
|
MessageUtils.findMessageNames(new Class[]{VpnManager.class}, new String[]{"TYPE_VPN_"});
|
||||||
|
|
||||||
|
/** Type of this VPN. */
|
||||||
|
@VpnManager.VpnType public final int type;
|
||||||
|
|
||||||
|
public VpnTransportInfo(@VpnManager.VpnType int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof VpnTransportInfo)) return false;
|
||||||
|
|
||||||
|
VpnTransportInfo that = (VpnTransportInfo) o;
|
||||||
|
return this.type == that.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final String typeString = sTypeToString.get(type, "VPN_TYPE_???");
|
||||||
|
return String.format("VpnTransportInfo{%s}", typeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeInt(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final @NonNull Creator<VpnTransportInfo> CREATOR =
|
||||||
|
new Creator<VpnTransportInfo>() {
|
||||||
|
public VpnTransportInfo createFromParcel(Parcel in) {
|
||||||
|
return new VpnTransportInfo(in.readInt());
|
||||||
|
}
|
||||||
|
public VpnTransportInfo[] newArray(int size) {
|
||||||
|
return new VpnTransportInfo[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
|
|||||||
import static android.net.NetworkRequest.Type.LISTEN;
|
import static android.net.NetworkRequest.Type.LISTEN;
|
||||||
import static android.net.NetworkRequest.Type.REQUEST;
|
import static android.net.NetworkRequest.Type.REQUEST;
|
||||||
import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
|
import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
|
||||||
|
import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
|
||||||
import static android.net.QosCallback.QosCallbackRegistrationException;
|
import static android.net.QosCallback.QosCallbackRegistrationException;
|
||||||
|
|
||||||
import android.annotation.CallbackExecutor;
|
import android.annotation.CallbackExecutor;
|
||||||
@@ -3721,7 +3722,8 @@ public class ConnectivityManager {
|
|||||||
printStackTrace();
|
printStackTrace();
|
||||||
checkCallbackNotNull(callback);
|
checkCallbackNotNull(callback);
|
||||||
Preconditions.checkArgument(
|
Preconditions.checkArgument(
|
||||||
reqType == TRACK_DEFAULT || need != null, "null NetworkCapabilities");
|
reqType == TRACK_DEFAULT || reqType == TRACK_SYSTEM_DEFAULT || need != null,
|
||||||
|
"null NetworkCapabilities");
|
||||||
final NetworkRequest request;
|
final NetworkRequest request;
|
||||||
final String callingPackageName = mContext.getOpPackageName();
|
final String callingPackageName = mContext.getOpPackageName();
|
||||||
try {
|
try {
|
||||||
@@ -4192,8 +4194,9 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers to receive notifications about changes in the system default network. The callbacks
|
* Registers to receive notifications about changes in the application's default network. This
|
||||||
* will continue to be called until either the application exits or
|
* may be a physical network or a virtual network, such as a VPN that applies to the
|
||||||
|
* application. The callbacks will continue to be called until either the application exits or
|
||||||
* {@link #unregisterNetworkCallback(NetworkCallback)} is called.
|
* {@link #unregisterNetworkCallback(NetworkCallback)} is called.
|
||||||
*
|
*
|
||||||
* <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
|
* <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
|
||||||
@@ -4206,7 +4209,7 @@ public class ConnectivityManager {
|
|||||||
* {@link #unregisterNetworkCallback(NetworkCallback)}.
|
* {@link #unregisterNetworkCallback(NetworkCallback)}.
|
||||||
*
|
*
|
||||||
* @param networkCallback The {@link NetworkCallback} that the system will call as the
|
* @param networkCallback The {@link NetworkCallback} that the system will call as the
|
||||||
* system default network changes.
|
* application's default network changes.
|
||||||
* The callback is invoked on the default internal Handler.
|
* The callback is invoked on the default internal Handler.
|
||||||
* @throws RuntimeException if the app already has too many callbacks registered.
|
* @throws RuntimeException if the app already has too many callbacks registered.
|
||||||
*/
|
*/
|
||||||
@@ -4215,11 +4218,47 @@ public class ConnectivityManager {
|
|||||||
registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
|
registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers to receive notifications about changes in the application's default network. This
|
||||||
|
* may be a physical network or a virtual network, such as a VPN that applies to the
|
||||||
|
* application. The callbacks will continue to be called until either the application exits or
|
||||||
|
* {@link #unregisterNetworkCallback(NetworkCallback)} is called.
|
||||||
|
*
|
||||||
|
* <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
|
||||||
|
* number of outstanding requests to 100 per app (identified by their UID), shared with
|
||||||
|
* all variants of this method, of {@link #requestNetwork} as well as
|
||||||
|
* {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
|
||||||
|
* Requesting a network with this method will count toward this limit. If this limit is
|
||||||
|
* exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
|
||||||
|
* make sure to unregister the callbacks with
|
||||||
|
* {@link #unregisterNetworkCallback(NetworkCallback)}.
|
||||||
|
*
|
||||||
|
* @param networkCallback The {@link NetworkCallback} that the system will call as the
|
||||||
|
* application's default network changes.
|
||||||
|
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
|
||||||
|
* @throws RuntimeException if the app already has too many callbacks registered.
|
||||||
|
*/
|
||||||
|
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||||
|
public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
|
||||||
|
@NonNull Handler handler) {
|
||||||
|
CallbackHandler cbHandler = new CallbackHandler(handler);
|
||||||
|
sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0,
|
||||||
|
TRACK_DEFAULT, TYPE_NONE, cbHandler);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers to receive notifications about changes in the system default network. The callbacks
|
* Registers to receive notifications about changes in the system default network. The callbacks
|
||||||
* will continue to be called until either the application exits or
|
* will continue to be called until either the application exits or
|
||||||
* {@link #unregisterNetworkCallback(NetworkCallback)} is called.
|
* {@link #unregisterNetworkCallback(NetworkCallback)} is called.
|
||||||
*
|
*
|
||||||
|
* This method should not be used to determine networking state seen by applications, because in
|
||||||
|
* many cases, most or even all application traffic may not use the default network directly,
|
||||||
|
* and traffic from different applications may go on different networks by default. As an
|
||||||
|
* example, if a VPN is connected, traffic from all applications might be sent through the VPN
|
||||||
|
* and not onto the system default network. Applications or system components desiring to do
|
||||||
|
* determine network state as seen by applications should use other methods such as
|
||||||
|
* {@link #registerDefaultNetworkCallback(NetworkCallback, Handler)}.
|
||||||
|
*
|
||||||
* <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
|
* <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
|
||||||
* number of outstanding requests to 100 per app (identified by their UID), shared with
|
* number of outstanding requests to 100 per app (identified by their UID), shared with
|
||||||
* all variants of this method, of {@link #requestNetwork} as well as
|
* all variants of this method, of {@link #requestNetwork} as well as
|
||||||
@@ -4233,20 +4272,19 @@ public class ConnectivityManager {
|
|||||||
* system default network changes.
|
* system default network changes.
|
||||||
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
|
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
|
||||||
* @throws RuntimeException if the app already has too many callbacks registered.
|
* @throws RuntimeException if the app already has too many callbacks registered.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
@SystemApi(client = MODULE_LIBRARIES)
|
||||||
public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
|
@SuppressLint({"ExecutorRegistration", "PairedRegistration"})
|
||||||
|
@RequiresPermission(anyOf = {
|
||||||
|
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
|
||||||
|
android.Manifest.permission.NETWORK_SETTINGS})
|
||||||
|
public void registerSystemDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
|
||||||
@NonNull Handler handler) {
|
@NonNull Handler handler) {
|
||||||
// This works because if the NetworkCapabilities are null,
|
|
||||||
// ConnectivityService takes them from the default request.
|
|
||||||
//
|
|
||||||
// Since the capabilities are exactly the same as the default request's
|
|
||||||
// capabilities, this request is guaranteed, at all times, to be
|
|
||||||
// satisfied by the same network, if any, that satisfies the default
|
|
||||||
// request, i.e., the system default network.
|
|
||||||
CallbackHandler cbHandler = new CallbackHandler(handler);
|
CallbackHandler cbHandler = new CallbackHandler(handler);
|
||||||
sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0,
|
sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0,
|
||||||
TRACK_DEFAULT, TYPE_NONE, cbHandler);
|
TRACK_SYSTEM_DEFAULT, TYPE_NONE, cbHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -762,12 +762,14 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
final int originalSignalStrength = mSignalStrength;
|
final int originalSignalStrength = mSignalStrength;
|
||||||
final int originalOwnerUid = getOwnerUid();
|
final int originalOwnerUid = getOwnerUid();
|
||||||
final int[] originalAdministratorUids = getAdministratorUids();
|
final int[] originalAdministratorUids = getAdministratorUids();
|
||||||
|
final TransportInfo originalTransportInfo = getTransportInfo();
|
||||||
clearAll();
|
clearAll();
|
||||||
mTransportTypes = (originalTransportTypes & TEST_NETWORKS_ALLOWED_TRANSPORTS)
|
mTransportTypes = (originalTransportTypes & TEST_NETWORKS_ALLOWED_TRANSPORTS)
|
||||||
| (1 << TRANSPORT_TEST);
|
| (1 << TRANSPORT_TEST);
|
||||||
mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
|
mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
|
||||||
mNetworkSpecifier = originalSpecifier;
|
mNetworkSpecifier = originalSpecifier;
|
||||||
mSignalStrength = originalSignalStrength;
|
mSignalStrength = originalSignalStrength;
|
||||||
|
mTransportInfo = originalTransportInfo;
|
||||||
|
|
||||||
// Only retain the owner and administrator UIDs if they match the app registering the remote
|
// Only retain the owner and administrator UIDs if they match the app registering the remote
|
||||||
// caller that registered the network.
|
// caller that registered the network.
|
||||||
|
|||||||
@@ -104,17 +104,14 @@ public class NetworkRequest implements Parcelable {
|
|||||||
* callbacks about the single, highest scoring current network
|
* callbacks about the single, highest scoring current network
|
||||||
* (if any) that matches the specified NetworkCapabilities, or
|
* (if any) that matches the specified NetworkCapabilities, or
|
||||||
*
|
*
|
||||||
* - TRACK_DEFAULT, a hybrid of the two designed such that the
|
* - TRACK_DEFAULT, which causes the framework to issue callbacks for
|
||||||
* framework will issue callbacks for the single, highest scoring
|
* the single, highest scoring current network (if any) that will
|
||||||
* current network (if any) that matches the capabilities of the
|
* be chosen for an app, but which cannot cause the framework to
|
||||||
* default Internet request (mDefaultRequest), but which cannot cause
|
* either create or retain the existence of any specific network.
|
||||||
* the framework to either create or retain the existence of any
|
*
|
||||||
* specific network. Note that from the point of view of the request
|
* - TRACK_SYSTEM_DEFAULT, which causes the framework to send callbacks
|
||||||
* matching code, TRACK_DEFAULT is identical to REQUEST: its special
|
* for the network (if any) that satisfies the default Internet
|
||||||
* behaviour is not due to different semantics, but to the fact that
|
* request.
|
||||||
* the system will only ever create a TRACK_DEFAULT with capabilities
|
|
||||||
* that are identical to the default request's capabilities, thus
|
|
||||||
* causing it to share fate in every way with the default request.
|
|
||||||
*
|
*
|
||||||
* - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
|
* - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
|
||||||
* to retain the NET_CAPABILITY_FOREGROUND capability. A network with
|
* to retain the NET_CAPABILITY_FOREGROUND capability. A network with
|
||||||
@@ -137,6 +134,7 @@ public class NetworkRequest implements Parcelable {
|
|||||||
TRACK_DEFAULT,
|
TRACK_DEFAULT,
|
||||||
REQUEST,
|
REQUEST,
|
||||||
BACKGROUND_REQUEST,
|
BACKGROUND_REQUEST,
|
||||||
|
TRACK_SYSTEM_DEFAULT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -601,6 +599,8 @@ public class NetworkRequest implements Parcelable {
|
|||||||
return NetworkRequestProto.TYPE_REQUEST;
|
return NetworkRequestProto.TYPE_REQUEST;
|
||||||
case BACKGROUND_REQUEST:
|
case BACKGROUND_REQUEST:
|
||||||
return NetworkRequestProto.TYPE_BACKGROUND_REQUEST;
|
return NetworkRequestProto.TYPE_BACKGROUND_REQUEST;
|
||||||
|
case TRACK_SYSTEM_DEFAULT:
|
||||||
|
return NetworkRequestProto.TYPE_TRACK_SYSTEM_DEFAULT;
|
||||||
default:
|
default:
|
||||||
return NetworkRequestProto.TYPE_UNKNOWN;
|
return NetworkRequestProto.TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,13 +55,29 @@ import java.security.GeneralSecurityException;
|
|||||||
public class VpnManager {
|
public class VpnManager {
|
||||||
/** Type representing a lack of VPN @hide */
|
/** Type representing a lack of VPN @hide */
|
||||||
public static final int TYPE_VPN_NONE = -1;
|
public static final int TYPE_VPN_NONE = -1;
|
||||||
/** VPN service type code @hide */
|
|
||||||
|
/**
|
||||||
|
* A VPN created by an app using the {@link VpnService} API.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public static final int TYPE_VPN_SERVICE = 1;
|
public static final int TYPE_VPN_SERVICE = 1;
|
||||||
/** Platform VPN type code @hide */
|
|
||||||
|
/**
|
||||||
|
* A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public static final int TYPE_VPN_PLATFORM = 2;
|
public static final int TYPE_VPN_PLATFORM = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IPsec VPN created by the built-in LegacyVpnRunner.
|
||||||
|
* @deprecated new Android devices should use VPN_TYPE_PLATFORM instead.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final int TYPE_VPN_LEGACY = 3;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM})
|
@IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM, TYPE_VPN_LEGACY})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface VpnType {}
|
public @interface VpnType {}
|
||||||
|
|
||||||
|
|||||||
@@ -132,12 +132,14 @@ import android.net.RouteInfo;
|
|||||||
import android.net.RouteInfoParcel;
|
import android.net.RouteInfoParcel;
|
||||||
import android.net.SocketKeepalive;
|
import android.net.SocketKeepalive;
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
|
import android.net.TransportInfo;
|
||||||
import android.net.UidRange;
|
import android.net.UidRange;
|
||||||
import android.net.UidRangeParcel;
|
import android.net.UidRangeParcel;
|
||||||
import android.net.UnderlyingNetworkInfo;
|
import android.net.UnderlyingNetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.VpnManager;
|
import android.net.VpnManager;
|
||||||
import android.net.VpnService;
|
import android.net.VpnService;
|
||||||
|
import android.net.VpnTransportInfo;
|
||||||
import android.net.metrics.INetdEventListener;
|
import android.net.metrics.INetdEventListener;
|
||||||
import android.net.metrics.IpConnectivityLog;
|
import android.net.metrics.IpConnectivityLog;
|
||||||
import android.net.metrics.NetworkEvent;
|
import android.net.metrics.NetworkEvent;
|
||||||
@@ -5747,6 +5749,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
throw new SecurityException("Insufficient permissions to specify legacy type");
|
throw new SecurityException("Insufficient permissions to specify legacy type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities;
|
||||||
final int callingUid = mDeps.getCallingUid();
|
final int callingUid = mDeps.getCallingUid();
|
||||||
final NetworkRequest.Type reqType;
|
final NetworkRequest.Type reqType;
|
||||||
try {
|
try {
|
||||||
@@ -5757,11 +5760,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
switch (reqType) {
|
switch (reqType) {
|
||||||
case TRACK_DEFAULT:
|
case TRACK_DEFAULT:
|
||||||
// If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
|
// If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
|
||||||
// is unused and will be replaced by the one from the default network request.
|
// is unused and will be replaced by ones appropriate for the caller.
|
||||||
// This allows callers to keep track of the system default network.
|
// This allows callers to keep track of the default network for their app.
|
||||||
networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid);
|
networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid);
|
||||||
enforceAccessPermission();
|
enforceAccessPermission();
|
||||||
break;
|
break;
|
||||||
|
case TRACK_SYSTEM_DEFAULT:
|
||||||
|
enforceSettingsPermission();
|
||||||
|
networkCapabilities = new NetworkCapabilities(defaultNc);
|
||||||
|
break;
|
||||||
case BACKGROUND_REQUEST:
|
case BACKGROUND_REQUEST:
|
||||||
enforceNetworkStackOrSettingsPermission();
|
enforceNetworkStackOrSettingsPermission();
|
||||||
// Fall-through since other checks are the same with normal requests.
|
// Fall-through since other checks are the same with normal requests.
|
||||||
@@ -5780,6 +5787,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
ensureRequestableCapabilities(networkCapabilities);
|
ensureRequestableCapabilities(networkCapabilities);
|
||||||
ensureSufficientPermissionsForRequest(networkCapabilities,
|
ensureSufficientPermissionsForRequest(networkCapabilities,
|
||||||
Binder.getCallingPid(), callingUid, callingPackageName);
|
Binder.getCallingPid(), callingUid, callingPackageName);
|
||||||
|
|
||||||
// Set the UID range for this request to the single UID of the requester, or to an empty
|
// Set the UID range for this request to the single UID of the requester, or to an empty
|
||||||
// set of UIDs if the caller has the appropriate permission and UIDs have not been set.
|
// set of UIDs if the caller has the appropriate permission and UIDs have not been set.
|
||||||
// This will overwrite any allowed UIDs in the requested capabilities. Though there
|
// This will overwrite any allowed UIDs in the requested capabilities. Though there
|
||||||
@@ -5799,6 +5807,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
new NetworkRequestInfo(messenger, networkRequest, binder, callingAttributionTag);
|
new NetworkRequestInfo(messenger, networkRequest, binder, callingAttributionTag);
|
||||||
if (DBG) log("requestNetwork for " + nri);
|
if (DBG) log("requestNetwork for " + nri);
|
||||||
|
|
||||||
|
// For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
|
||||||
|
// copied from the default request above. (This is necessary to ensure, for example, that
|
||||||
|
// the callback does not leak sensitive information to unprivileged apps.) Check that the
|
||||||
|
// changes don't alter request matching.
|
||||||
|
if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT &&
|
||||||
|
(!networkCapabilities.equalRequestableCapabilities(defaultNc))) {
|
||||||
|
Log.wtf(TAG, "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
|
||||||
|
+ networkCapabilities + " vs. " + defaultNc);
|
||||||
|
}
|
||||||
|
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
|
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
|
||||||
if (timeoutMs > 0) {
|
if (timeoutMs > 0) {
|
||||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
|
mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
|
||||||
@@ -8462,22 +8480,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private @VpnManager.VpnType int getVpnType(@Nullable NetworkAgentInfo vpn) {
|
||||||
* Caller either needs to be an active VPN, or hold the NETWORK_STACK permission
|
if (vpn == null) return VpnManager.TYPE_VPN_NONE;
|
||||||
* for testing.
|
final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
|
||||||
*/
|
if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE;
|
||||||
private Vpn enforceActiveVpnOrNetworkStackPermission() {
|
return ((VpnTransportInfo) ti).type;
|
||||||
if (checkNetworkStackPermission()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
synchronized (mVpns) {
|
|
||||||
Vpn vpn = getVpnIfOwner();
|
|
||||||
if (vpn != null) {
|
|
||||||
return vpn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new SecurityException("App must either be an active VPN or have the NETWORK_STACK "
|
|
||||||
+ "permission");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8487,14 +8494,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
* connection is not found.
|
* connection is not found.
|
||||||
*/
|
*/
|
||||||
public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
|
public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
|
||||||
final Vpn vpn = enforceActiveVpnOrNetworkStackPermission();
|
|
||||||
|
|
||||||
// Only VpnService based VPNs should be able to get this information.
|
|
||||||
if (vpn != null && vpn.getActiveAppVpnType() != VpnManager.TYPE_VPN_SERVICE) {
|
|
||||||
throw new SecurityException(
|
|
||||||
"getConnectionOwnerUid() not allowed for non-VpnService VPNs");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
|
if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
|
||||||
throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
|
throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
|
||||||
}
|
}
|
||||||
@@ -8502,8 +8501,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol,
|
final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol,
|
||||||
connectionInfo.local, connectionInfo.remote);
|
connectionInfo.local, connectionInfo.remote);
|
||||||
|
|
||||||
/* Filter out Uids not associated with the VPN. */
|
if (uid == INVALID_UID) return uid; // Not found.
|
||||||
if (vpn != null && !vpn.appliesToUid(uid)) {
|
|
||||||
|
// Connection owner UIDs are visible only to the network stack and to the VpnService-based
|
||||||
|
// VPN, if any, that applies to the UID that owns the connection.
|
||||||
|
if (checkNetworkStackPermission()) return uid;
|
||||||
|
|
||||||
|
final NetworkAgentInfo vpn = getVpnForUid(uid);
|
||||||
|
if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE
|
||||||
|
|| vpn.networkCapabilities.getOwnerUid() != Binder.getCallingUid()) {
|
||||||
return INVALID_UID;
|
return INVALID_UID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -717,8 +717,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
mNumBackgroundNetworkRequests += delta;
|
mNumBackgroundNetworkRequests += delta;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRACK_DEFAULT:
|
|
||||||
case LISTEN:
|
case LISTEN:
|
||||||
|
case TRACK_DEFAULT:
|
||||||
|
case TRACK_SYSTEM_DEFAULT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NONE:
|
case NONE:
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
|||||||
import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
|
import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
|
||||||
import static android.net.NetworkRequest.Type.REQUEST;
|
import static android.net.NetworkRequest.Type.REQUEST;
|
||||||
import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
|
import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
|
||||||
|
import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
@@ -329,6 +330,9 @@ public class ConnectivityManagerTest {
|
|||||||
mustFail(() -> { manager.registerDefaultNetworkCallback(null, handler); });
|
mustFail(() -> { manager.registerDefaultNetworkCallback(null, handler); });
|
||||||
mustFail(() -> { manager.registerDefaultNetworkCallback(callback, null); });
|
mustFail(() -> { manager.registerDefaultNetworkCallback(callback, null); });
|
||||||
|
|
||||||
|
mustFail(() -> { manager.registerSystemDefaultNetworkCallback(null, handler); });
|
||||||
|
mustFail(() -> { manager.registerSystemDefaultNetworkCallback(callback, null); });
|
||||||
|
|
||||||
mustFail(() -> { manager.unregisterNetworkCallback(nullCallback); });
|
mustFail(() -> { manager.unregisterNetworkCallback(nullCallback); });
|
||||||
mustFail(() -> { manager.unregisterNetworkCallback(nullIntent); });
|
mustFail(() -> { manager.unregisterNetworkCallback(nullIntent); });
|
||||||
mustFail(() -> { manager.releaseNetworkRequest(nullIntent); });
|
mustFail(() -> { manager.releaseNetworkRequest(nullIntent); });
|
||||||
@@ -377,6 +381,13 @@ public class ConnectivityManagerTest {
|
|||||||
eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
|
eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
|
||||||
eq(testPkgName), eq(testAttributionTag));
|
eq(testPkgName), eq(testAttributionTag));
|
||||||
reset(mService);
|
reset(mService);
|
||||||
|
|
||||||
|
Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
|
||||||
|
manager.registerSystemDefaultNetworkCallback(callback, handler);
|
||||||
|
verify(mService).requestNetwork(eq(null),
|
||||||
|
eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
|
||||||
|
eq(testPkgName), eq(testAttributionTag));
|
||||||
|
reset(mService);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Message makeMessage(NetworkRequest req, int messageType) {
|
static Message makeMessage(NetworkRequest req, int messageType) {
|
||||||
|
|||||||
51
tests/net/java/android/net/VpnTransportInfoTest.java
Normal file
51
tests/net/java/android/net/VpnTransportInfoTest.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.net;
|
||||||
|
|
||||||
|
import static com.android.testutils.ParcelUtils.assertParcelSane;
|
||||||
|
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public class VpnTransportInfoTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParceling() {
|
||||||
|
VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM);
|
||||||
|
assertParcelSane(v, 1 /* fieldCount */);
|
||||||
|
assertParcelingIsLossless(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsAndHashCode() {
|
||||||
|
VpnTransportInfo v1 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM);
|
||||||
|
VpnTransportInfo v2 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE);
|
||||||
|
VpnTransportInfo v3 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM);
|
||||||
|
assertNotEquals(v1, v2);
|
||||||
|
assertEquals(v1, v3);
|
||||||
|
assertEquals(v1.hashCode(), v3.hashCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -205,6 +205,7 @@ import android.net.UidRangeParcel;
|
|||||||
import android.net.UnderlyingNetworkInfo;
|
import android.net.UnderlyingNetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.VpnManager;
|
import android.net.VpnManager;
|
||||||
|
import android.net.VpnTransportInfo;
|
||||||
import android.net.metrics.IpConnectivityLog;
|
import android.net.metrics.IpConnectivityLog;
|
||||||
import android.net.shared.NetworkMonitorUtils;
|
import android.net.shared.NetworkMonitorUtils;
|
||||||
import android.net.shared.PrivateDnsConfig;
|
import android.net.shared.PrivateDnsConfig;
|
||||||
@@ -1110,7 +1111,7 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getActiveAppVpnType() {
|
public int getActiveVpnType() {
|
||||||
return mVpnType;
|
return mVpnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1123,10 +1124,12 @@ public class ConnectivityServiceTest {
|
|||||||
private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp)
|
private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
if (mAgentRegistered) throw new IllegalStateException("already registered");
|
if (mAgentRegistered) throw new IllegalStateException("already registered");
|
||||||
|
updateState(NetworkInfo.DetailedState.CONNECTING, "registerAgent");
|
||||||
mConfig = new VpnConfig();
|
mConfig = new VpnConfig();
|
||||||
setUids(uids);
|
setUids(uids);
|
||||||
if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
|
if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||||
mInterface = VPN_IFNAME;
|
mInterface = VPN_IFNAME;
|
||||||
|
mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType()));
|
||||||
mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp,
|
mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp,
|
||||||
mNetworkCapabilities);
|
mNetworkCapabilities);
|
||||||
mMockNetworkAgent.waitForIdle(TIMEOUT_MS);
|
mMockNetworkAgent.waitForIdle(TIMEOUT_MS);
|
||||||
@@ -3649,10 +3652,19 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterDefaultNetworkCallback() throws Exception {
|
public void testRegisterDefaultNetworkCallback() throws Exception {
|
||||||
|
// NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback.
|
||||||
|
mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS,
|
||||||
|
PERMISSION_GRANTED);
|
||||||
|
|
||||||
final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
|
final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
|
||||||
mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
|
mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
|
||||||
defaultNetworkCallback.assertNoCallback();
|
defaultNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
final Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
|
||||||
|
final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback();
|
||||||
|
mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, handler);
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
|
|
||||||
// Create a TRANSPORT_CELLULAR request to keep the mobile interface up
|
// Create a TRANSPORT_CELLULAR request to keep the mobile interface up
|
||||||
// whenever Wi-Fi is up. Without this, the mobile network agent is
|
// whenever Wi-Fi is up. Without this, the mobile network agent is
|
||||||
// reaped before any other activity can take place.
|
// reaped before any other activity can take place.
|
||||||
@@ -3667,27 +3679,35 @@ public class ConnectivityServiceTest {
|
|||||||
mCellNetworkAgent.connect(true);
|
mCellNetworkAgent.connect(true);
|
||||||
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||||
defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||||
|
systemDefaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||||
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
|
||||||
// Bring up wifi and expect CALLBACK_AVAILABLE.
|
// Bring up wifi and expect CALLBACK_AVAILABLE.
|
||||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||||
mWiFiNetworkAgent.connect(true);
|
mWiFiNetworkAgent.connect(true);
|
||||||
cellNetworkCallback.assertNoCallback();
|
cellNetworkCallback.assertNoCallback();
|
||||||
defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
|
defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
|
||||||
|
systemDefaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
|
||||||
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
|
||||||
// Bring down cell. Expect no default network callback, since it wasn't the default.
|
// Bring down cell. Expect no default network callback, since it wasn't the default.
|
||||||
mCellNetworkAgent.disconnect();
|
mCellNetworkAgent.disconnect();
|
||||||
cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||||
defaultNetworkCallback.assertNoCallback();
|
defaultNetworkCallback.assertNoCallback();
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
|
||||||
// Bring up cell. Expect no default network callback, since it won't be the default.
|
// Bring up cell. Expect no default network callback, since it won't be the default.
|
||||||
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
||||||
mCellNetworkAgent.connect(true);
|
mCellNetworkAgent.connect(true);
|
||||||
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||||
defaultNetworkCallback.assertNoCallback();
|
defaultNetworkCallback.assertNoCallback();
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
|
||||||
// Bring down wifi. Expect the default network callback to notified of LOST wifi
|
// Bring down wifi. Expect the default network callback to notified of LOST wifi
|
||||||
// followed by AVAILABLE cell.
|
// followed by AVAILABLE cell.
|
||||||
@@ -3695,19 +3715,25 @@ public class ConnectivityServiceTest {
|
|||||||
cellNetworkCallback.assertNoCallback();
|
cellNetworkCallback.assertNoCallback();
|
||||||
defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
||||||
defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
|
defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
|
||||||
|
systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
||||||
|
systemDefaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
|
||||||
mCellNetworkAgent.disconnect();
|
mCellNetworkAgent.disconnect();
|
||||||
cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||||
defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||||
|
systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||||
waitForIdle();
|
waitForIdle();
|
||||||
assertEquals(null, mCm.getActiveNetwork());
|
assertEquals(null, mCm.getActiveNetwork());
|
||||||
|
|
||||||
mMockVpn.establishForMyUid();
|
mMockVpn.establishForMyUid();
|
||||||
assertUidRangesUpdatedForMyUid(true);
|
assertUidRangesUpdatedForMyUid(true);
|
||||||
defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
assertEquals(null, systemDefaultCallback.getLastAvailableNetwork());
|
||||||
|
|
||||||
mMockVpn.disconnect();
|
mMockVpn.disconnect();
|
||||||
defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
waitForIdle();
|
waitForIdle();
|
||||||
assertEquals(null, mCm.getActiveNetwork());
|
assertEquals(null, mCm.getActiveNetwork());
|
||||||
}
|
}
|
||||||
@@ -6134,6 +6160,10 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVpnNetworkActive() throws Exception {
|
public void testVpnNetworkActive() throws Exception {
|
||||||
|
// NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback.
|
||||||
|
mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS,
|
||||||
|
PERMISSION_GRANTED);
|
||||||
|
|
||||||
final int uid = Process.myUid();
|
final int uid = Process.myUid();
|
||||||
|
|
||||||
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
|
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
|
||||||
@@ -6141,6 +6171,7 @@ public class ConnectivityServiceTest {
|
|||||||
final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
|
final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
|
||||||
final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
|
final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
|
||||||
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
|
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
|
||||||
|
final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback();
|
||||||
final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build();
|
final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build();
|
||||||
final NetworkRequest genericRequest = new NetworkRequest.Builder()
|
final NetworkRequest genericRequest = new NetworkRequest.Builder()
|
||||||
.removeCapability(NET_CAPABILITY_NOT_VPN).build();
|
.removeCapability(NET_CAPABILITY_NOT_VPN).build();
|
||||||
@@ -6154,6 +6185,8 @@ public class ConnectivityServiceTest {
|
|||||||
mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
|
mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
|
||||||
mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
|
mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
|
||||||
mCm.registerDefaultNetworkCallback(defaultCallback);
|
mCm.registerDefaultNetworkCallback(defaultCallback);
|
||||||
|
mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback,
|
||||||
|
new Handler(ConnectivityThread.getInstanceLooper()));
|
||||||
defaultCallback.assertNoCallback();
|
defaultCallback.assertNoCallback();
|
||||||
|
|
||||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||||
@@ -6163,6 +6196,7 @@ public class ConnectivityServiceTest {
|
|||||||
genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
|
systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
vpnNetworkCallback.assertNoCallback();
|
vpnNetworkCallback.assertNoCallback();
|
||||||
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
|
||||||
@@ -6183,7 +6217,10 @@ public class ConnectivityServiceTest {
|
|||||||
wifiNetworkCallback.assertNoCallback();
|
wifiNetworkCallback.assertNoCallback();
|
||||||
vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||||
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||||
|
assertEquals(mWiFiNetworkAgent.getNetwork(),
|
||||||
|
systemDefaultCallback.getLastAvailableNetwork());
|
||||||
|
|
||||||
ranges.clear();
|
ranges.clear();
|
||||||
mMockVpn.setUids(ranges);
|
mMockVpn.setUids(ranges);
|
||||||
@@ -6200,6 +6237,7 @@ public class ConnectivityServiceTest {
|
|||||||
// much, but that is the reason the test here has to check for an update to the
|
// much, but that is the reason the test here has to check for an update to the
|
||||||
// capabilities instead of the expected LOST then AVAILABLE.
|
// capabilities instead of the expected LOST then AVAILABLE.
|
||||||
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
|
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
|
|
||||||
ranges.add(new UidRange(uid, uid));
|
ranges.add(new UidRange(uid, uid));
|
||||||
mMockVpn.setUids(ranges);
|
mMockVpn.setUids(ranges);
|
||||||
@@ -6211,6 +6249,7 @@ public class ConnectivityServiceTest {
|
|||||||
// TODO : Here like above, AVAILABLE would be correct, but because this can't actually
|
// TODO : Here like above, AVAILABLE would be correct, but because this can't actually
|
||||||
// happen outside of the test, ConnectivityService does not rematch callbacks.
|
// happen outside of the test, ConnectivityService does not rematch callbacks.
|
||||||
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
|
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
|
|
||||||
mWiFiNetworkAgent.disconnect();
|
mWiFiNetworkAgent.disconnect();
|
||||||
|
|
||||||
@@ -6219,6 +6258,7 @@ public class ConnectivityServiceTest {
|
|||||||
wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
||||||
vpnNetworkCallback.assertNoCallback();
|
vpnNetworkCallback.assertNoCallback();
|
||||||
defaultCallback.assertNoCallback();
|
defaultCallback.assertNoCallback();
|
||||||
|
systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
||||||
|
|
||||||
mMockVpn.disconnect();
|
mMockVpn.disconnect();
|
||||||
|
|
||||||
@@ -6227,12 +6267,14 @@ public class ConnectivityServiceTest {
|
|||||||
wifiNetworkCallback.assertNoCallback();
|
wifiNetworkCallback.assertNoCallback();
|
||||||
vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
||||||
defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
||||||
|
systemDefaultCallback.assertNoCallback();
|
||||||
assertEquals(null, mCm.getActiveNetwork());
|
assertEquals(null, mCm.getActiveNetwork());
|
||||||
|
|
||||||
mCm.unregisterNetworkCallback(genericNetworkCallback);
|
mCm.unregisterNetworkCallback(genericNetworkCallback);
|
||||||
mCm.unregisterNetworkCallback(wifiNetworkCallback);
|
mCm.unregisterNetworkCallback(wifiNetworkCallback);
|
||||||
mCm.unregisterNetworkCallback(vpnNetworkCallback);
|
mCm.unregisterNetworkCallback(vpnNetworkCallback);
|
||||||
mCm.unregisterNetworkCallback(defaultCallback);
|
mCm.unregisterNetworkCallback(defaultCallback);
|
||||||
|
mCm.unregisterNetworkCallback(systemDefaultCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -7283,6 +7325,7 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void establishLegacyLockdownVpn() throws Exception {
|
private void establishLegacyLockdownVpn() throws Exception {
|
||||||
|
mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY);
|
||||||
// The legacy lockdown VPN only supports userId 0.
|
// The legacy lockdown VPN only supports userId 0.
|
||||||
final Set<UidRange> ranges = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
|
final Set<UidRange> ranges = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
|
||||||
mMockVpn.registerAgent(ranges);
|
mMockVpn.registerAgent(ranges);
|
||||||
@@ -7395,6 +7438,9 @@ public class ConnectivityServiceTest {
|
|||||||
assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR));
|
assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR));
|
||||||
assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI));
|
assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI));
|
||||||
assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED));
|
assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||||
|
VpnTransportInfo ti = (VpnTransportInfo) vpnNc.getTransportInfo();
|
||||||
|
assertNotNull(ti);
|
||||||
|
assertEquals(VpnManager.TYPE_VPN_LEGACY, ti.type);
|
||||||
|
|
||||||
// Switch default network from cell to wifi. Expect VPN to disconnect and reconnect.
|
// Switch default network from cell to wifi. Expect VPN to disconnect and reconnect.
|
||||||
final LinkProperties wifiLp = new LinkProperties();
|
final LinkProperties wifiLp = new LinkProperties();
|
||||||
@@ -8521,11 +8567,7 @@ public class ConnectivityServiceTest {
|
|||||||
final int myUid = Process.myUid();
|
final int myUid = Process.myUid();
|
||||||
setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM);
|
setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM);
|
||||||
|
|
||||||
try {
|
assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo()));
|
||||||
mService.getConnectionOwnerUid(getTestConnectionInfo());
|
|
||||||
fail("Expected SecurityException for non-VpnService app");
|
|
||||||
} catch (SecurityException expected) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -8533,11 +8575,7 @@ public class ConnectivityServiceTest {
|
|||||||
final int myUid = Process.myUid();
|
final int myUid = Process.myUid();
|
||||||
setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE);
|
setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE);
|
||||||
|
|
||||||
try {
|
assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo()));
|
||||||
mService.getConnectionOwnerUid(getTestConnectionInfo());
|
|
||||||
fail("Expected SecurityException for non-VpnService app");
|
|
||||||
} catch (SecurityException expected) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static android.net.ConnectivityManager.NetworkCallback;
|
|||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
@@ -74,6 +75,7 @@ import android.net.UidRange;
|
|||||||
import android.net.UidRangeParcel;
|
import android.net.UidRangeParcel;
|
||||||
import android.net.VpnManager;
|
import android.net.VpnManager;
|
||||||
import android.net.VpnService;
|
import android.net.VpnService;
|
||||||
|
import android.net.VpnTransportInfo;
|
||||||
import android.net.ipsec.ike.IkeSessionCallback;
|
import android.net.ipsec.ike.IkeSessionCallback;
|
||||||
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
@@ -984,6 +986,13 @@ public class VpnTest {
|
|||||||
startRacoon("hostname", "5.6.7.8"); // address returned by deps.resolve
|
startRacoon("hostname", "5.6.7.8"); // address returned by deps.resolve
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertTransportInfoMatches(NetworkCapabilities nc, int type) {
|
||||||
|
assertNotNull(nc);
|
||||||
|
VpnTransportInfo ti = (VpnTransportInfo) nc.getTransportInfo();
|
||||||
|
assertNotNull(ti);
|
||||||
|
assertEquals(type, ti.type);
|
||||||
|
}
|
||||||
|
|
||||||
public void startRacoon(final String serverAddr, final String expectedAddr)
|
public void startRacoon(final String serverAddr, final String expectedAddr)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
final ConditionVariable legacyRunnerReady = new ConditionVariable();
|
final ConditionVariable legacyRunnerReady = new ConditionVariable();
|
||||||
@@ -1020,8 +1029,10 @@ public class VpnTest {
|
|||||||
|
|
||||||
// Now wait for the runner to be ready before testing for the route.
|
// Now wait for the runner to be ready before testing for the route.
|
||||||
ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class);
|
ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class);
|
||||||
|
ArgumentCaptor<NetworkCapabilities> ncCaptor =
|
||||||
|
ArgumentCaptor.forClass(NetworkCapabilities.class);
|
||||||
verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(),
|
verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(),
|
||||||
lpCaptor.capture(), any(), anyInt(), any(), anyInt());
|
lpCaptor.capture(), ncCaptor.capture(), anyInt(), any(), anyInt());
|
||||||
|
|
||||||
// In this test the expected address is always v4 so /32.
|
// In this test the expected address is always v4 so /32.
|
||||||
// Note that the interface needs to be specified because RouteInfo objects stored in
|
// Note that the interface needs to be specified because RouteInfo objects stored in
|
||||||
@@ -1031,6 +1042,8 @@ public class VpnTest {
|
|||||||
final List<RouteInfo> actualRoutes = lpCaptor.getValue().getRoutes();
|
final List<RouteInfo> actualRoutes = lpCaptor.getValue().getRoutes();
|
||||||
assertTrue("Expected throw route (" + expectedRoute + ") not found in " + actualRoutes,
|
assertTrue("Expected throw route (" + expectedRoute + ") not found in " + actualRoutes,
|
||||||
actualRoutes.contains(expectedRoute));
|
actualRoutes.contains(expectedRoute));
|
||||||
|
|
||||||
|
assertTransportInfoMatches(ncCaptor.getValue(), VpnManager.TYPE_VPN_LEGACY);
|
||||||
} finally {
|
} finally {
|
||||||
// Now interrupt the thread, unblock the runner and clean up.
|
// Now interrupt the thread, unblock the runner and clean up.
|
||||||
vpn.mVpnRunner.exitVpnRunner();
|
vpn.mVpnRunner.exitVpnRunner();
|
||||||
|
|||||||
Reference in New Issue
Block a user