deps);
}
+ private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
+ final NetworkCapabilities netCap = new NetworkCapabilities();
+ netCap.addCapability(NET_CAPABILITY_INTERNET);
+ netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
+ netCap.setSingleUid(uid);
+ return netCap;
+ }
+
private NetworkRequest createDefaultInternetRequestForTransport(
int transportType, NetworkRequest.Type type) {
NetworkCapabilities netCap = new NetworkCapabilities();
int vpnNetId = NETID_UNSET;
synchronized (mVpns) {
final Vpn vpn = mVpns.get(user);
+ // TODO : now that capabilities contain the UID, the appliesToUid test should
+ // be removed as the satisfying test below should be enough.
if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId();
}
NetworkAgentInfo nai;
if (vpnNetId != NETID_UNSET) {
nai = getNetworkAgentInfoForNetId(vpnNetId);
- if (nai != null) return nai.network;
+ if (nai != null) {
+ final NetworkCapabilities requiredCaps =
+ createDefaultNetworkCapabilitiesForUid(uid);
+ if (requiredCaps.satisfiedByNetworkCapabilities(nai.networkCapabilities)) {
+ return nai.network;
+ }
+ }
}
nai = getDefaultNetwork();
if (nai != null
private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
NetworkCapabilities nc, int callerPid, int callerUid) {
final NetworkCapabilities newNc = new NetworkCapabilities(nc);
- if (!checkSettingsPermission(callerPid, callerUid)) newNc.setUids(null);
- if (!checkSettingsPermission(callerPid, callerUid)) newNc.setSSID(null);
+ if (!checkSettingsPermission(callerPid, callerUid)) {
+ newNc.setUids(null);
+ newNc.setSSID(null);
+ }
return newNc;
}
// the default network request. This allows callers to keep track of
// the system default network.
if (type == NetworkRequest.Type.TRACK_DEFAULT) {
- networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities);
- networkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN);
+ networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid());
enforceAccessPermission();
} else {
networkCapabilities = new NetworkCapabilities(networkCapabilities);
// Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
private final NetworkRequest mDefaultRequest;
-
+
// Request used to optionally keep mobile data active even when higher
// priority networks like Wi-Fi are active.
private final NetworkRequest mDefaultMobileDataRequest;
mCm.unregisterNetworkCallback(vpnNetworkCallback);
mCm.unregisterNetworkCallback(defaultCallback);
}
+
+ @Test
+ public void testVpnWithAndWithoutInternet() {
+ final int uid = Process.myUid();
+
+ final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+ mCm.registerDefaultNetworkCallback(defaultCallback);
+ defaultCallback.assertNoCallback();
+
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(true);
+
+ defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
+ assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
+
+ MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+ final ArraySet<UidRange> ranges = new ArraySet<>();
+ ranges.add(new UidRange(uid, uid));
+ when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
+ vpnNetworkAgent.setUids(ranges);
+ vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */);
+
+ defaultCallback.assertNoCallback();
+ assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
+
+ vpnNetworkAgent.disconnect();
+ defaultCallback.assertNoCallback();
+
+ vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+ when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
+ vpnNetworkAgent.setUids(ranges);
+ vpnNetworkAgent.connect(true /* validated */, true /* hasInternet */);
+ defaultCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent);
+ assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
+
+ vpnNetworkAgent.disconnect();
+ defaultCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+ defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
+
+ vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+ when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
+ ranges.clear();
+ vpnNetworkAgent.setUids(ranges);
+
+ vpnNetworkAgent.connect(false /* validated */, true /* hasInternet */);
+ defaultCallback.assertNoCallback();
+
+ mCm.unregisterNetworkCallback(defaultCallback);
+ }
}