diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index a7bbc53366..adc16f1a5c 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -170,4 +170,5 @@ interface IConnectivityManager boolean addVpnAddress(String address, int prefixLength); boolean removeVpnAddress(String address, int prefixLength); + boolean setUnderlyingNetworksForVpn(in Network[] networks); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index ec0e15c2d5..b1e932d388 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -865,6 +865,29 @@ public class ConnectivityService extends IConnectivityManager.Stub Network network = null; NetworkAgentInfo nai = mNetworkForRequestId.get(mDefaultRequest.requestId); + + if (!mLockdownEnabled) { + int user = UserHandle.getUserId(uid); + synchronized (mVpns) { + Vpn vpn = mVpns.get(user); + if (vpn != null && vpn.appliesToUid(uid)) { + // getUnderlyingNetworks() returns: + // null => the VPN didn't specify anything, so we use the default. + // empty array => the VPN explicitly said "no default network". + // non-empty array => the VPN specified one or more default networks; we use the + // first one. + Network[] networks = vpn.getUnderlyingNetworks(); + if (networks != null) { + if (networks.length > 0) { + nai = getNetworkAgentInfoForNetwork(networks[0]); + } else { + nai = null; + } + } + } + } + } + if (nai != null) { synchronized (nai) { info = new NetworkInfo(nai.networkInfo); @@ -4376,4 +4399,13 @@ public class ConnectivityService extends IConnectivityManager.Stub return mVpns.get(user).removeAddress(address, prefixLength); } } + + @Override + public boolean setUnderlyingNetworksForVpn(Network[] networks) { + throwIfLockdownEnabled(); + int user = UserHandle.getUserId(Binder.getCallingUid()); + synchronized (mVpns) { + return mVpns.get(user).setUnderlyingNetworks(networks); + } + } }