diff options
4 files changed, 177 insertions, 212 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f0561177fc9c..9b006d050c02 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -41,6 +41,7 @@ import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 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_ROAMING; @@ -6354,18 +6355,71 @@ public class ConnectivityService extends IConnectivityManager.Stub nai.declaredMetered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); } - /** Propagates to |nc| the capabilities declared by the underlying networks of |nai|. */ - private void mixInUnderlyingCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { - Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; - Network defaultNetwork = getNetwork(getDefaultNetwork()); + /** Modifies |caps| based on the capabilities of the specified underlying networks. */ + @VisibleForTesting + void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks, + @NonNull NetworkCapabilities caps, boolean declaredMetered) { + final Network defaultNetwork = getNetwork(getDefaultNetwork()); if (underlyingNetworks == null && defaultNetwork != null) { // null underlying networks means to track the default. underlyingNetworks = new Network[] { defaultNetwork }; } + int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN }; + int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; + int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; + boolean metered = declaredMetered; // metered if any underlying is metered, or agentMetered + boolean roaming = false; // roaming if any underlying is roaming + boolean congested = false; // congested if any underlying is congested + boolean suspended = true; // suspended if all underlying are suspended + + boolean hadUnderlyingNetworks = false; + if (null != underlyingNetworks) { + for (Network underlyingNetwork : underlyingNetworks) { + final NetworkAgentInfo underlying = + getNetworkAgentInfoForNetwork(underlyingNetwork); + if (underlying == null) continue; + + final NetworkCapabilities underlyingCaps = underlying.networkCapabilities; + hadUnderlyingNetworks = true; + for (int underlyingType : underlyingCaps.getTransportTypes()) { + transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType); + } - // TODO(b/124469351): Get capabilities directly from ConnectivityService instead. - final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); - Vpn.applyUnderlyingCapabilities(cm, underlyingNetworks, nc, nai.declaredMetered); + // Merge capabilities of this underlying network. For bandwidth, assume the + // worst case. + downKbps = NetworkCapabilities.minBandwidth(downKbps, + underlyingCaps.getLinkDownstreamBandwidthKbps()); + upKbps = NetworkCapabilities.minBandwidth(upKbps, + underlyingCaps.getLinkUpstreamBandwidthKbps()); + // If this underlying network is metered, the VPN is metered (it may cost money + // to send packets on this network). + metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); + // If this underlying network is roaming, the VPN is roaming (the billing structure + // is different than the usual, local one). + roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); + // If this underlying network is congested, the VPN is congested (the current + // condition of the network affects the performance of this network). + congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); + // If this network is not suspended, the VPN is not suspended (the VPN + // is able to transfer some data). + suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); + } + } + if (!hadUnderlyingNetworks) { + // No idea what the underlying networks are; assume reasonable defaults + metered = true; + roaming = false; + congested = false; + suspended = false; + } + + caps.setTransportTypes(transportTypes); + caps.setLinkDownstreamBandwidthKbps(downKbps); + caps.setLinkUpstreamBandwidthKbps(upKbps); + caps.setCapability(NET_CAPABILITY_NOT_METERED, !metered); + caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); + caps.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); + caps.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended); } /** @@ -6422,7 +6476,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (nai.supportsUnderlyingNetworks()) { - mixInUnderlyingCapabilities(nai, newNc); + applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, newNc, nai.declaredMetered); } return newNc; diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 234dcc9d74a5..3445275b76dd 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -18,10 +18,7 @@ package com.android.server.connectivity; import static android.Manifest.permission.BIND_VPN_SERVICE; import static android.net.ConnectivityManager.NETID_UNSET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_UNREACHABLE; @@ -111,7 +108,6 @@ import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnInfo; import com.android.internal.net.VpnProfile; -import com.android.internal.util.ArrayUtils; import com.android.server.DeviceIdleInternal; import com.android.server.LocalServices; import com.android.server.net.BaseNetworkObserver; @@ -463,99 +459,6 @@ public class Vpn { } /** - * Updates {@link #mNetworkCapabilities} based on current underlying networks and returns a - * defensive copy. - * - * <p>Does not propagate updated capabilities to apps. - * - * @param defaultNetwork underlying network for VPNs following platform's default - */ - public synchronized NetworkCapabilities updateCapabilities(@Nullable Network defaultNetwork) { - if (mConfig == null) { - // VPN is not running. - return null; - } - - Network[] underlyingNetworks = mConfig.underlyingNetworks; - if (underlyingNetworks == null && defaultNetwork != null) { - // null underlying networks means to track the default. - underlyingNetworks = new Network[] { defaultNetwork }; - } - // Only apps targeting Q and above can explicitly declare themselves as metered. - final boolean isAlwaysMetered = mIsPackageTargetingAtLeastQ && mConfig.isMetered; - - applyUnderlyingCapabilities( - mConnectivityManager, - underlyingNetworks, - mNetworkCapabilities, - isAlwaysMetered); - - return new NetworkCapabilities(mNetworkCapabilities); - } - - @VisibleForTesting - public static void applyUnderlyingCapabilities( - @NonNull final ConnectivityManager cm, - @Nullable final Network[] underlyingNetworks, - @NonNull final NetworkCapabilities caps, - final boolean isAlwaysMetered) { - int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN }; - int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; - int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; - boolean metered = isAlwaysMetered; // metered if any underlying is metered, or alwaysMetered - boolean roaming = false; // roaming if any underlying is roaming - boolean congested = false; // congested if any underlying is congested - boolean suspended = true; // suspended if all underlying are suspended - - boolean hadUnderlyingNetworks = false; - if (null != underlyingNetworks) { - for (Network underlying : underlyingNetworks) { - // TODO(b/124469351): Get capabilities directly from ConnectivityService instead. - final NetworkCapabilities underlyingCaps = cm.getNetworkCapabilities(underlying); - if (underlyingCaps == null) continue; - hadUnderlyingNetworks = true; - for (int underlyingType : underlyingCaps.getTransportTypes()) { - transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType); - } - - // Merge capabilities of this underlying network. For bandwidth, assume the - // worst case. - downKbps = NetworkCapabilities.minBandwidth(downKbps, - underlyingCaps.getLinkDownstreamBandwidthKbps()); - upKbps = NetworkCapabilities.minBandwidth(upKbps, - underlyingCaps.getLinkUpstreamBandwidthKbps()); - // If this underlying network is metered, the VPN is metered (it may cost money - // to send packets on this network). - metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); - // If this underlying network is roaming, the VPN is roaming (the billing structure - // is different than the usual, local one). - roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); - // If this underlying network is congested, the VPN is congested (the current - // condition of the network affects the performance of this network). - congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); - // If this network is not suspended, the VPN is not suspended (the VPN - // is able to transfer some data). - suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); - } - } - if (!hadUnderlyingNetworks) { - // No idea what the underlying networks are; assume the safer defaults - metered = true; - roaming = false; - congested = false; - suspended = false; - } - - caps.setTransportTypes(transportTypes); - caps.setLinkDownstreamBandwidthKbps(downKbps); - caps.setLinkUpstreamBandwidthKbps(upKbps); - caps.setCapability(NET_CAPABILITY_NOT_METERED, !metered); - caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); - caps.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); - caps.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended); - } - - /** * Chooses whether to force all connections to go though VPN. * * Used to enable/disable legacy VPN lockdown. diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 95419cfb9364..7a1cb25b2d3a 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -56,8 +56,10 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 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_ROAMING; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; @@ -5398,6 +5400,106 @@ public class ConnectivityServiceTest { } @Test + public void testApplyUnderlyingCapabilities() throws Exception { + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); + mCellNetworkAgent.connect(false /* validated */); + mWiFiNetworkAgent.connect(false /* validated */); + + final NetworkCapabilities cellNc = new NetworkCapabilities() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_INTERNET) + .addCapability(NET_CAPABILITY_NOT_CONGESTED) + .setLinkDownstreamBandwidthKbps(10); + final NetworkCapabilities wifiNc = new NetworkCapabilities() + .addTransportType(TRANSPORT_WIFI) + .addCapability(NET_CAPABILITY_INTERNET) + .addCapability(NET_CAPABILITY_NOT_METERED) + .addCapability(NET_CAPABILITY_NOT_ROAMING) + .addCapability(NET_CAPABILITY_NOT_CONGESTED) + .addCapability(NET_CAPABILITY_NOT_SUSPENDED) + .setLinkUpstreamBandwidthKbps(20); + mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); + mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); + waitForIdle(); + + final Network mobile = mCellNetworkAgent.getNetwork(); + final Network wifi = mWiFiNetworkAgent.getNetwork(); + + final NetworkCapabilities initialCaps = new NetworkCapabilities(); + initialCaps.addCapability(NET_CAPABILITY_INTERNET); + initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN); + + final NetworkCapabilities withNoUnderlying = new NetworkCapabilities(); + withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET); + withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED); + withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING); + withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED); + withNoUnderlying.addTransportType(TRANSPORT_VPN); + withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN); + + final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying); + withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); + withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); + withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); + withMobileUnderlying.setLinkDownstreamBandwidthKbps(10); + + final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying); + withWifiUnderlying.addTransportType(TRANSPORT_WIFI); + withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); + withWifiUnderlying.setLinkUpstreamBandwidthKbps(20); + + final NetworkCapabilities withWifiAndMobileUnderlying = + new NetworkCapabilities(withNoUnderlying); + withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); + withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI); + withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); + withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); + withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10); + withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20); + + NetworkCapabilities caps = new NetworkCapabilities(initialCaps); + final boolean notDeclaredMetered = false; + mService.applyUnderlyingCapabilities(new Network[]{}, caps, notDeclaredMetered); + assertEquals(withNoUnderlying, caps); + + caps = new NetworkCapabilities(initialCaps); + mService.applyUnderlyingCapabilities(new Network[]{null}, caps, notDeclaredMetered); + assertEquals(withNoUnderlying, caps); + + caps = new NetworkCapabilities(initialCaps); + mService.applyUnderlyingCapabilities(new Network[]{mobile}, caps, notDeclaredMetered); + assertEquals(withMobileUnderlying, caps); + + mService.applyUnderlyingCapabilities(new Network[]{wifi}, caps, notDeclaredMetered); + assertEquals(withWifiUnderlying, caps); + + final boolean isDeclaredMetered = true; + withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); + caps = new NetworkCapabilities(initialCaps); + mService.applyUnderlyingCapabilities(new Network[]{wifi}, caps, isDeclaredMetered); + assertEquals(withWifiUnderlying, caps); + + caps = new NetworkCapabilities(initialCaps); + mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, caps, isDeclaredMetered); + assertEquals(withWifiAndMobileUnderlying, caps); + + withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); + caps = new NetworkCapabilities(initialCaps); + mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, + caps, notDeclaredMetered); + assertEquals(withWifiAndMobileUnderlying, caps); + + caps = new NetworkCapabilities(initialCaps); + mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, + caps, notDeclaredMetered); + assertEquals(withWifiAndMobileUnderlying, caps); + + mService.applyUnderlyingCapabilities(null, caps, notDeclaredMetered); + assertEquals(withWifiUnderlying, caps); + } + + @Test public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception { final TestNetworkCallback callback = new TestNetworkCallback(); final NetworkRequest request = new NetworkRequest.Builder() @@ -5947,17 +6049,28 @@ public class ConnectivityServiceTest { && caps.hasTransport(TRANSPORT_VPN) && caps.hasTransport(TRANSPORT_WIFI)); + // Change the VPN's capabilities somehow (specifically, disconnect wifi). + mWiFiNetworkAgent.disconnect(); + callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); + callback.expectCapabilitiesThat(mMockVpn, (caps) + -> caps.getUids().size() == 2 + && caps.getUids().contains(new UidRange(uid, uid)) + && caps.getUids().contains(UidRange.createForUser(restrictedUserId)) + && caps.hasTransport(TRANSPORT_VPN) + && !caps.hasTransport(TRANSPORT_WIFI)); + // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. final Intent removedIntent = new Intent(ACTION_USER_REMOVED); removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId); handler.post(() -> mServiceContext.sendBroadcast(removedIntent)); - // Expect that the VPN gains the UID range for the restricted user. + // Expect that the VPN gains the UID range for the restricted user, and that the capability + // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. callback.expectCapabilitiesThat(mMockVpn, (caps) -> caps.getUids().size() == 1 && caps.getUids().contains(new UidRange(uid, uid)) && caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_WIFI)); + && !caps.hasTransport(TRANSPORT_WIFI)); } @Test diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index d0db55f2bb13..337507ac1d46 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -21,15 +21,6 @@ import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; import static android.content.pm.UserInfo.FLAG_PRIMARY; import static android.content.pm.UserInfo.FLAG_RESTRICTED; import static android.net.ConnectivityManager.NetworkCallback; -import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_VPN; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -621,102 +612,6 @@ public class VpnTest { order.verify(mNotificationManager).cancel(anyString(), anyInt()); } - @Test - public void testCapabilities() { - setMockedUsers(primaryUser); - - final Network mobile = new Network(1); - final Network wifi = new Network(2); - - final Map<Network, NetworkCapabilities> networks = new HashMap<>(); - networks.put( - mobile, - new NetworkCapabilities() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_NOT_CONGESTED) - .setLinkDownstreamBandwidthKbps(10)); - networks.put( - wifi, - new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI) - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_NOT_METERED) - .addCapability(NET_CAPABILITY_NOT_ROAMING) - .addCapability(NET_CAPABILITY_NOT_CONGESTED) - .addCapability(NET_CAPABILITY_NOT_SUSPENDED) - .setLinkUpstreamBandwidthKbps(20)); - setMockedNetworks(networks); - - final NetworkCapabilities caps = new NetworkCapabilities(); - - Vpn.applyUnderlyingCapabilities( - mConnectivityManager, new Network[] {}, caps, false /* isAlwaysMetered */); - assertTrue(caps.hasTransport(TRANSPORT_VPN)); - assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); - assertFalse(caps.hasTransport(TRANSPORT_WIFI)); - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps()); - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps()); - assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - - Vpn.applyUnderlyingCapabilities( - mConnectivityManager, - new Network[] {mobile}, - caps, - false /* isAlwaysMetered */); - assertTrue(caps.hasTransport(TRANSPORT_VPN)); - assertTrue(caps.hasTransport(TRANSPORT_CELLULAR)); - assertFalse(caps.hasTransport(TRANSPORT_WIFI)); - assertEquals(10, caps.getLinkDownstreamBandwidthKbps()); - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps()); - assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - - Vpn.applyUnderlyingCapabilities( - mConnectivityManager, new Network[] {wifi}, caps, false /* isAlwaysMetered */); - assertTrue(caps.hasTransport(TRANSPORT_VPN)); - assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); - assertTrue(caps.hasTransport(TRANSPORT_WIFI)); - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps()); - assertEquals(20, caps.getLinkUpstreamBandwidthKbps()); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - - Vpn.applyUnderlyingCapabilities( - mConnectivityManager, new Network[] {wifi}, caps, true /* isAlwaysMetered */); - assertTrue(caps.hasTransport(TRANSPORT_VPN)); - assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); - assertTrue(caps.hasTransport(TRANSPORT_WIFI)); - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps()); - assertEquals(20, caps.getLinkUpstreamBandwidthKbps()); - assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - - Vpn.applyUnderlyingCapabilities( - mConnectivityManager, - new Network[] {mobile, wifi}, - caps, - false /* isAlwaysMetered */); - assertTrue(caps.hasTransport(TRANSPORT_VPN)); - assertTrue(caps.hasTransport(TRANSPORT_CELLULAR)); - assertTrue(caps.hasTransport(TRANSPORT_WIFI)); - assertEquals(10, caps.getLinkDownstreamBandwidthKbps()); - assertEquals(20, caps.getLinkUpstreamBandwidthKbps()); - assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - } - /** * The profile name should NOT change between releases for backwards compatibility * |