Merge "Update documentation for AES-GCM-ESP keymat length"
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 0ccebc1..6bf1425 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -619,6 +619,35 @@
*/
public static final int NETID_UNSET = 0;
+ /**
+ * Private DNS Mode values.
+ *
+ * The "private_dns_mode" global setting stores a String value which is
+ * expected to be one of the following.
+ */
+
+ /**
+ * @hide
+ */
+ public static final String PRIVATE_DNS_MODE_OFF = "off";
+ /**
+ * @hide
+ */
+ public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
+ /**
+ * @hide
+ */
+ public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
+ /**
+ * The default Private DNS mode.
+ *
+ * This may change from release to release or may become dependent upon
+ * the capabilities of the underlying platform.
+ *
+ * @hide
+ */
+ public static final String PRIVATE_DNS_DEFAULT_MODE = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+
private final IConnectivityManager mService;
/**
* A kludge to facilitate static access where a Context pointer isn't available, like in the
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
new file mode 100644
index 0000000..e76d17d
--- /dev/null
+++ b/core/java/android/net/MacAddress.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 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 com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Arrays;
+
+/**
+ * @hide
+ */
+public final class MacAddress {
+
+ // TODO: add isLocallyAssigned().
+ // TODO: add getRandomAddress() factory method.
+
+ private static final int ETHER_ADDR_LEN = 6;
+ private static final byte FF = (byte) 0xff;
+ @VisibleForTesting
+ static final byte[] ETHER_ADDR_BROADCAST = { FF, FF, FF, FF, FF, FF };
+
+ public enum MacAddressType {
+ UNICAST,
+ MULTICAST,
+ BROADCAST;
+ }
+
+ /** Return true if the given byte array is not null and has the length of a mac address. */
+ public static boolean isMacAddress(byte[] addr) {
+ return addr != null && addr.length == ETHER_ADDR_LEN;
+ }
+
+ /**
+ * Return the MacAddressType of the mac address represented by the given byte array,
+ * or null if the given byte array does not represent an mac address. */
+ public static MacAddressType macAddressType(byte[] addr) {
+ if (!isMacAddress(addr)) {
+ return null;
+ }
+ if (Arrays.equals(addr, ETHER_ADDR_BROADCAST)) {
+ return MacAddressType.BROADCAST;
+ }
+ if ((addr[0] & 0x01) == 1) {
+ return MacAddressType.MULTICAST;
+ }
+ return MacAddressType.UNICAST;
+ }
+}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index db12dd9..ee75fd4 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -17,6 +17,7 @@
package android.net;
import android.annotation.IntDef;
+import android.net.ConnectivityManager.NetworkCallback;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,15 +31,24 @@
import java.util.StringJoiner;
/**
- * This class represents the capabilities of a network. This is used both to specify
- * needs to {@link ConnectivityManager} and when inspecting a network.
- *
- * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
- * of network selection. Rather than indicate a need for Wi-Fi because an application
- * needs high bandwidth and risk obsolescence when a new, fast network appears (like LTE),
- * the application should specify it needs high bandwidth. Similarly if an application
- * needs an unmetered network for a bulk transfer it can specify that rather than assuming
- * all cellular based connections are metered and all Wi-Fi based connections are not.
+ * Representation of the capabilities of a network. This object serves two
+ * purposes:
+ * <ul>
+ * <li>An expression of the current capabilities of an active network, typically
+ * expressed through
+ * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)}
+ * or {@link ConnectivityManager#getNetworkCapabilities(Network)}.
+ * <li>An expression of the future capabilities of a desired network, typically
+ * expressed through {@link NetworkRequest}.
+ * </ul>
+ * <p>
+ * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of
+ * network selection. Rather than indicate a need for Wi-Fi because an
+ * application needs high bandwidth and risk obsolescence when a new, fast
+ * network appears (like LTE), the application should specify it needs high
+ * bandwidth. Similarly if an application needs an unmetered network for a bulk
+ * transfer it can specify that rather than assuming all cellular based
+ * connections are metered and all Wi-Fi based connections are not.
*/
public final class NetworkCapabilities implements Parcelable {
private static final String TAG = "NetworkCapabilities";
@@ -101,6 +111,7 @@
NET_CAPABILITY_NOT_VPN,
NET_CAPABILITY_VALIDATED,
NET_CAPABILITY_CAPTIVE_PORTAL,
+ NET_CAPABILITY_NOT_ROAMING,
NET_CAPABILITY_FOREGROUND,
})
public @interface NetCapability { }
@@ -218,11 +229,16 @@
public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
/**
+ * Indicates that this network is not roaming.
+ */
+ public static final int NET_CAPABILITY_NOT_ROAMING = 18;
+
+ /**
* Indicates that this network is available for use by apps, and not a network that is being
* kept up in the background to facilitate fast network switching.
* @hide
*/
- public static final int NET_CAPABILITY_FOREGROUND = 18;
+ public static final int NET_CAPABILITY_FOREGROUND = 19;
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND;
@@ -237,6 +253,7 @@
(1 << NET_CAPABILITY_TRUSTED) |
(1 << NET_CAPABILITY_VALIDATED) |
(1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
+ (1 << NET_CAPABILITY_NOT_ROAMING) |
(1 << NET_CAPABILITY_FOREGROUND);
/**
@@ -316,6 +333,21 @@
}
/**
+ * Sets (or clears) the given capability on this {@link NetworkCapabilities}
+ * instance.
+ *
+ * @hide
+ */
+ public NetworkCapabilities setCapability(@NetCapability int capability, boolean value) {
+ if (value) {
+ addCapability(capability);
+ } else {
+ removeCapability(capability);
+ }
+ return this;
+ }
+
+ /**
* Gets all the capabilities set on this {@code NetworkCapability} instance.
*
* @return an array of capability values for this instance.
@@ -326,6 +358,15 @@
}
/**
+ * Sets all the capabilities set on this {@code NetworkCapability} instance.
+ *
+ * @hide
+ */
+ public void setCapabilities(@NetCapability int[] capabilities) {
+ mNetworkCapabilities = BitUtils.packBits(capabilities);
+ }
+
+ /**
* Tests for the presence of a capabilitity on this instance.
*
* @param capability the capabilities to be tested for.
@@ -515,6 +556,21 @@
}
/**
+ * Sets (or clears) the given transport on this {@link NetworkCapabilities}
+ * instance.
+ *
+ * @hide
+ */
+ public NetworkCapabilities setTransportType(@Transport int transportType, boolean value) {
+ if (value) {
+ addTransportType(transportType);
+ } else {
+ removeTransportType(transportType);
+ }
+ return this;
+ }
+
+ /**
* Gets all the transports set on this {@code NetworkCapability} instance.
*
* @return an array of transport type values for this instance.
@@ -525,6 +581,15 @@
}
/**
+ * Sets all the transports set on this {@code NetworkCapability} instance.
+ *
+ * @hide
+ */
+ public void setTransportTypes(@Transport int[] transportTypes) {
+ mTransportTypes = BitUtils.packBits(transportTypes);
+ }
+
+ /**
* Tests for the presence of a transport on this instance.
*
* @param transportType the transport type to be tested for.
@@ -549,12 +614,18 @@
}
/**
+ * Value indicating that link bandwidth is unspecified.
+ * @hide
+ */
+ public static final int LINK_BANDWIDTH_UNSPECIFIED = 0;
+
+ /**
* Passive link bandwidth. This is a rough guide of the expected peak bandwidth
* for the first hop on the given transport. It is not measured, but may take into account
* link parameters (Radio technology, allocated channels, etc).
*/
- private int mLinkUpBandwidthKbps;
- private int mLinkDownBandwidthKbps;
+ private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
+ private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
/**
* Sets the upstream bandwidth for this network in Kbps. This always only refers to
@@ -571,8 +642,9 @@
* @param upKbps the estimated first hop upstream (device to network) bandwidth.
* @hide
*/
- public void setLinkUpstreamBandwidthKbps(int upKbps) {
+ public NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
mLinkUpBandwidthKbps = upKbps;
+ return this;
}
/**
@@ -600,8 +672,9 @@
* @param downKbps the estimated first hop downstream (network to device) bandwidth.
* @hide
*/
- public void setLinkDownstreamBandwidthKbps(int downKbps) {
+ public NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
mLinkDownBandwidthKbps = downKbps;
+ return this;
}
/**
@@ -628,6 +701,20 @@
return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
}
+ /** @hide */
+ public static int minBandwidth(int a, int b) {
+ if (a == LINK_BANDWIDTH_UNSPECIFIED) {
+ return b;
+ } else if (b == LINK_BANDWIDTH_UNSPECIFIED) {
+ return a;
+ } else {
+ return Math.min(a, b);
+ }
+ }
+ /** @hide */
+ public static int maxBandwidth(int a, int b) {
+ return Math.max(a, b);
+ }
private NetworkSpecifier mNetworkSpecifier = null;
@@ -708,8 +795,9 @@
* @param signalStrength the bearer-specific signal strength.
* @hide
*/
- public void setSignalStrength(int signalStrength) {
+ public NetworkCapabilities setSignalStrength(int signalStrength) {
mSignalStrength = signalStrength;
+ return this;
}
/**
@@ -968,6 +1056,7 @@
case NET_CAPABILITY_NOT_VPN: return "NOT_VPN";
case NET_CAPABILITY_VALIDATED: return "VALIDATED";
case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL";
+ case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING";
case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
default: return Integer.toString(capability);
}
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 84c32be..d554938 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -307,11 +307,17 @@
}
/**
- * Indicates whether the device is currently roaming on this network.
- * When {@code true}, it suggests that use of data on this network
- * may incur extra costs.
+ * Indicates whether the device is currently roaming on this network. When
+ * {@code true}, it suggests that use of data on this network may incur
+ * extra costs.
+ *
* @return {@code true} if roaming is in effect, {@code false} otherwise.
+ * @deprecated Callers should switch to checking
+ * {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING}
+ * instead, since that handles more complex situations, such as
+ * VPNs.
*/
+ @Deprecated
public boolean isRoaming() {
synchronized (this) {
return mIsRoaming;
@@ -320,6 +326,7 @@
/** {@hide} */
@VisibleForTesting
+ @Deprecated
public void setRoaming(boolean isRoaming) {
synchronized (this) {
mIsRoaming = isRoaming;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 25c96d1..664c2ab 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -29,7 +29,10 @@
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_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.Nullable;
@@ -71,6 +74,7 @@
import android.net.RouteInfo;
import android.net.UidRange;
import android.net.Uri;
+import android.net.VpnService;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.util.MultinetworkPolicyTracker;
@@ -2109,9 +2113,14 @@
final boolean valid =
(msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
final boolean wasValidated = nai.lastValidated;
+ final boolean wasDefault = isDefaultNetwork(nai);
if (DBG) log(nai.name() + " validation " + (valid ? "passed" : "failed") +
(msg.obj == null ? "" : " with redirect to " + (String)msg.obj));
if (valid != nai.lastValidated) {
+ if (wasDefault) {
+ metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity(
+ SystemClock.elapsedRealtime(), valid);
+ }
final int oldScore = nai.getCurrentScore();
nai.lastValidated = valid;
nai.everValidated |= valid;
@@ -2283,7 +2292,8 @@
// Let rematchAllNetworksAndRequests() below record a new default network event
// if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
// whose timestamps tell how long it takes to recover a default network.
- metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(null, nai);
+ long now = SystemClock.elapsedRealtime();
+ metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
}
notifyIfacesChangedForNetworkStats();
// TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
@@ -4664,10 +4674,12 @@
}
}
- final NetworkCapabilities prevNc = nai.networkCapabilities;
+ final NetworkCapabilities prevNc;
synchronized (nai) {
+ prevNc = nai.networkCapabilities;
nai.networkCapabilities = networkCapabilities;
}
+
if (nai.getCurrentScore() == oldScore &&
networkCapabilities.equalRequestableCapabilities(prevNc)) {
// If the requestable capabilities haven't changed, and the score hasn't changed, then
@@ -4681,6 +4693,28 @@
rematchAllNetworksAndRequests(nai, oldScore);
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
}
+
+ // Report changes that are interesting for network statistics tracking.
+ if (prevNc != null) {
+ final boolean meteredChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_METERED) !=
+ networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED);
+ final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
+ networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+ if (meteredChanged || roamingChanged) {
+ notifyIfacesChangedForNetworkStats();
+ }
+ }
+
+ if (!networkCapabilities.hasTransport(TRANSPORT_VPN)) {
+ // Tell VPNs about updated capabilities, since they may need to
+ // bubble those changes through.
+ synchronized (mVpns) {
+ for (int i = 0; i < mVpns.size(); i++) {
+ final Vpn vpn = mVpns.valueAt(i);
+ vpn.updateCapabilities();
+ }
+ }
+ }
}
public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
@@ -5013,7 +5047,7 @@
makeDefault(newNetwork);
// Log 0 -> X and Y -> X default network transitions, where X is the new default.
metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(
- newNetwork, oldDefaultNetwork);
+ now, newNetwork, oldDefaultNetwork);
// Have a new default network, release the transition wakelock in
scheduleReleaseNetworkTransitionWakelock();
}
@@ -5214,14 +5248,6 @@
}
notifyLockdownVpn(networkAgent);
- if (oldInfo != null && oldInfo.getState() == state) {
- if (oldInfo.isRoaming() != newInfo.isRoaming()) {
- if (VDBG) log("roaming status changed, notifying NetworkStatsService");
- notifyIfacesChangedForNetworkStats();
- } else if (VDBG) log("ignoring duplicate network state non-change");
- // In either case, no further work should be needed.
- return;
- }
if (DBG) {
log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " +
(oldInfo == null ? "null" : oldInfo.getState()) +
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
new file mode 100644
index 0000000..3fa9c3a
--- /dev/null
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import android.net.MacAddress.MacAddressType;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class MacAddressTest {
+
+ static class AddrTypeTestCase {
+ byte[] addr;
+ MacAddressType expected;
+
+ static AddrTypeTestCase of(MacAddressType expected, int... addr) {
+ AddrTypeTestCase t = new AddrTypeTestCase();
+ t.expected = expected;
+ t.addr = toByteArray(addr);
+ return t;
+ }
+ }
+
+ @Test
+ public void testMacAddrTypes() {
+ AddrTypeTestCase[] testcases = {
+ AddrTypeTestCase.of(null),
+ AddrTypeTestCase.of(null, 0),
+ AddrTypeTestCase.of(null, 1, 2, 3, 4, 5),
+ AddrTypeTestCase.of(null, 1, 2, 3, 4, 5, 6, 7),
+ AddrTypeTestCase.of(MacAddressType.UNICAST, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0),
+ AddrTypeTestCase.of(MacAddressType.BROADCAST, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
+ AddrTypeTestCase.of(MacAddressType.MULTICAST, 1, 2, 3, 4, 5, 6),
+ AddrTypeTestCase.of(MacAddressType.MULTICAST, 11, 22, 33, 44, 55, 66),
+ AddrTypeTestCase.of(MacAddressType.MULTICAST, 33, 33, 0xaa, 0xbb, 0xcc, 0xdd)
+ };
+
+ for (AddrTypeTestCase t : testcases) {
+ MacAddressType got = MacAddress.macAddressType(t.addr);
+ String msg = String.format("expected type of %s to be %s, but got %s",
+ Arrays.toString(t.addr), t.expected, got);
+ assertEquals(msg, t.expected, got);
+ }
+ }
+
+ static byte[] toByteArray(int[] in) {
+ byte[] out = new byte[in.length];
+ for (int i = 0; i < in.length; i++) {
+ out[i] = (byte) in[i];
+ }
+ return out;
+ }
+}
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index 7346f9f..cd2d098 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -16,6 +16,7 @@
package android.net;
+import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -26,13 +27,12 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
-
-import android.net.NetworkCapabilities;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
@@ -159,4 +159,25 @@
assertNotEquals("", nc1.describeImmutableDifferences(nc2));
assertEquals("", nc1.describeImmutableDifferences(nc1));
}
+
+ @Test
+ public void testLinkBandwidthUtils() {
+ assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities
+ .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED));
+ assertEquals(10, NetworkCapabilities
+ .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10));
+ assertEquals(10, NetworkCapabilities
+ .minBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED));
+ assertEquals(10, NetworkCapabilities
+ .minBandwidth(10, 20));
+
+ assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities
+ .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED));
+ assertEquals(10, NetworkCapabilities
+ .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10));
+ assertEquals(10, NetworkCapabilities
+ .maxBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED));
+ assertEquals(20, NetworkCapabilities
+ .maxBandwidth(10, 20));
+ }
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 27a29b6..113cd37 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -23,21 +23,44 @@
import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.NetworkCapabilities.*;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
+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_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
+
+import static com.android.internal.util.TestUtils.waitForIdleHandler;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static com.android.internal.util.TestUtils.waitForIdleHandler;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
@@ -45,7 +68,6 @@
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
@@ -64,7 +86,6 @@
import android.net.Network;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
-import android.net.NetworkConfig;
import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
@@ -79,13 +100,9 @@
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
-import android.os.MessageQueue;
-import android.os.Messenger;
-import android.os.MessageQueue.IdleHandler;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
@@ -96,10 +113,8 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.mock.MockContentResolver;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
-import android.util.LogPrinter;
import com.android.internal.util.WakeupMessage;
import com.android.internal.util.test.BroadcastInterceptingContext;
@@ -109,7 +124,6 @@
import com.android.server.connectivity.MockableSystemProperties;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
-import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal;
@@ -160,6 +174,7 @@
@Mock IpConnectivityMetrics.Logger mMetricsService;
@Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
+ @Mock INetworkStatsService mStatsService;
// This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
// do not go through ConnectivityService but talk to netd directly, so they don't automatically
@@ -858,7 +873,7 @@
NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
mService = new WrappedConnectivityService(mServiceContext,
mock(INetworkManagementService.class),
- mock(INetworkStatsService.class),
+ mStatsService,
mock(INetworkPolicyManager.class),
mock(IpConnectivityLog.class));
@@ -3440,6 +3455,40 @@
mCm.unregisterNetworkCallback(networkCallback);
}
+ @Test
+ public void testStatsIfacesChanged() throws Exception {
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+
+ // Simple connection should have updated ifaces
+ mCellNetworkAgent.connect(false);
+ waitForIdle();
+ verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+ reset(mStatsService);
+
+ // Metered change should update ifaces
+ mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ waitForIdle();
+ verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+ reset(mStatsService);
+
+ mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ waitForIdle();
+ verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+ reset(mStatsService);
+
+ // Captive portal change shouldn't update ifaces
+ mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
+ waitForIdle();
+ verify(mStatsService, never()).forceUpdateIfaces();
+ reset(mStatsService);
+
+ // Roaming change should update ifaces
+ mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
+ waitForIdle();
+ verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
+ reset(mStatsService);
+ }
+
private void checkDirectlyConnectedRoutes(Object callbackObj,
Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) {
assertTrue(callbackObj instanceof LinkProperties);
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index ad6ebf9..a65bb24 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -198,37 +198,33 @@
@Test
public void testDefaultNetworkEventSerialization() {
- DefaultNetworkEvent ev = new DefaultNetworkEvent();
+ DefaultNetworkEvent ev = new DefaultNetworkEvent(1001);
ev.netId = 102;
- ev.prevNetId = 101;
- ev.transportTypes = new int[]{1, 2, 3};
- ev.prevIPv4 = true;
- ev.prevIPv6 = true;
+ ev.transports = 2;
+ ev.previousTransports = 4;
+ ev.ipv4 = true;
+ ev.initialScore = 20;
+ ev.finalScore = 60;
+ ev.durationMs = 54;
+ ev.validatedMs = 27;
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
- " link_layer: 0",
+ " link_layer: 4",
" network_id: 102",
" time_ms: 0",
- " transports: 0",
+ " transports: 2",
" default_network_event <",
- " default_network_duration_ms: 0",
- " final_score: 0",
- " initial_score: 0",
- " ip_support: 0",
- " network_id <",
- " network_id: 102",
- " >",
+ " default_network_duration_ms: 54",
+ " final_score: 60",
+ " initial_score: 20",
+ " ip_support: 1",
" no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 101",
- " >",
- " previous_network_ip_support: 3",
- " transport_types: 1",
- " transport_types: 2",
- " transport_types: 3",
+ " previous_default_network_link_layer: 1",
+ " previous_network_ip_support: 0",
+ " validation_duration_ms: 27",
" >",
">",
"version: 2\n");
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 6c1decc..b48ff8d 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -188,119 +188,99 @@
{makeNai(102, 50, true, true, cell), makeNai(103, 20, true, false, wifi)},
};
+ long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs;
+ long durationMs = 1001;
for (NetworkAgentInfo[] pair : defaultNetworks) {
- mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(pair[1], pair[0]);
+ timeMs += durationMs;
+ durationMs += durationMs;
+ mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs, pair[1], pair[0]);
}
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
- " link_layer: 0",
- " network_id: 100",
- " time_ms: 0",
- " transports: 0",
- " default_network_event <",
- " default_network_duration_ms: 0",
- " final_score: 0",
- " initial_score: 0",
- " ip_support: 0",
- " network_id <",
- " network_id: 100",
- " >",
- " no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 0",
- " >",
- " previous_network_ip_support: 0",
- " transport_types: 0",
- " >",
- ">",
- "events <",
- " if_name: \"\"",
- " link_layer: 0",
- " network_id: 101",
- " time_ms: 0",
- " transports: 0",
- " default_network_event <",
- " default_network_duration_ms: 0",
- " final_score: 0",
- " initial_score: 0",
- " ip_support: 0",
- " network_id <",
- " network_id: 101",
- " >",
- " no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 100",
- " >",
- " previous_network_ip_support: 3",
- " transport_types: 1",
- " >",
- ">",
- "events <",
- " if_name: \"\"",
- " link_layer: 0",
+ " link_layer: 5",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" default_network_event <",
- " default_network_duration_ms: 0",
+ " default_network_duration_ms: 1001",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
- " network_id <",
- " network_id: 0",
- " >",
" no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 101",
- " >",
- " previous_network_ip_support: 1",
+ " previous_default_network_link_layer: 0",
+ " previous_network_ip_support: 0",
+ " validation_duration_ms: 0",
" >",
">",
"events <",
" if_name: \"\"",
- " link_layer: 0",
+ " link_layer: 2",
+ " network_id: 100",
+ " time_ms: 0",
+ " transports: 1",
+ " default_network_event <",
+ " default_network_duration_ms: 2002",
+ " final_score: 50",
+ " initial_score: 10",
+ " ip_support: 3",
+ " no_default_network_duration_ms: 0",
+ " previous_default_network_link_layer: 0",
+ " previous_network_ip_support: 0",
+ " validation_duration_ms: 2002",
+ " >",
+ ">",
+ "events <",
+ " if_name: \"\"",
+ " link_layer: 4",
+ " network_id: 101",
+ " time_ms: 0",
+ " transports: 2",
+ " default_network_event <",
+ " default_network_duration_ms: 4004",
+ " final_score: 60",
+ " initial_score: 20",
+ " ip_support: 1",
+ " no_default_network_duration_ms: 0",
+ " previous_default_network_link_layer: 2",
+ " previous_network_ip_support: 0",
+ " validation_duration_ms: 4004",
+ " >",
+ ">",
+ "events <",
+ " if_name: \"\"",
+ " link_layer: 5",
+ " network_id: 0",
+ " time_ms: 0",
+ " transports: 0",
+ " default_network_event <",
+ " default_network_duration_ms: 8008",
+ " final_score: 0",
+ " initial_score: 0",
+ " ip_support: 0",
+ " no_default_network_duration_ms: 0",
+ " previous_default_network_link_layer: 4",
+ " previous_network_ip_support: 0",
+ " validation_duration_ms: 0",
+ " >",
+ ">",
+ "events <",
+ " if_name: \"\"",
+ " link_layer: 2",
" network_id: 102",
" time_ms: 0",
- " transports: 0",
+ " transports: 1",
" default_network_event <",
- " default_network_duration_ms: 0",
- " final_score: 0",
- " initial_score: 0",
- " ip_support: 0",
- " network_id <",
- " network_id: 102",
- " >",
+ " default_network_duration_ms: 16016",
+ " final_score: 50",
+ " initial_score: 10",
+ " ip_support: 3",
" no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 0",
- " >",
+ " previous_default_network_link_layer: 4",
" previous_network_ip_support: 0",
- " transport_types: 0",
- " >",
- ">",
- "events <",
- " if_name: \"\"",
- " link_layer: 0",
- " network_id: 103",
- " time_ms: 0",
- " transports: 0",
- " default_network_event <",
- " default_network_duration_ms: 0",
- " final_score: 0",
- " initial_score: 0",
- " ip_support: 0",
- " network_id <",
- " network_id: 103",
- " >",
- " no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 102",
- " >",
- " previous_network_ip_support: 3",
- " transport_types: 1",
+ " validation_duration_ms: 16016",
" >",
">",
"version: 2\n");
@@ -379,12 +359,13 @@
wakeupEvent("wlan0", 10008);
wakeupEvent("rmnet0", 1000);
+ long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs;
final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});
final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI});
NetworkAgentInfo cellNai = makeNai(100, 50, false, true, cell);
NetworkAgentInfo wifiNai = makeNai(101, 60, true, false, wifi);
- mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(cellNai, null);
- mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(wifiNai, cellNai);
+ mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 200, cellNai, null);
+ mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 300, wifiNai, cellNai);
String want = String.join("\n",
"dropped_events: 0",
@@ -473,46 +454,36 @@
">",
"events <",
" if_name: \"\"",
- " link_layer: 0",
- " network_id: 100",
+ " link_layer: 5",
+ " network_id: 0",
" time_ms: 0",
" transports: 0",
" default_network_event <",
- " default_network_duration_ms: 0",
+ " default_network_duration_ms: 200",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
- " network_id <",
- " network_id: 100",
- " >",
" no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 0",
- " >",
+ " previous_default_network_link_layer: 0",
" previous_network_ip_support: 0",
- " transport_types: 0",
+ " validation_duration_ms: 0",
" >",
">",
"events <",
" if_name: \"\"",
- " link_layer: 0",
- " network_id: 101",
+ " link_layer: 2",
+ " network_id: 100",
" time_ms: 0",
- " transports: 0",
+ " transports: 1",
" default_network_event <",
- " default_network_duration_ms: 0",
- " final_score: 0",
- " initial_score: 0",
- " ip_support: 0",
- " network_id <",
- " network_id: 101",
- " >",
+ " default_network_duration_ms: 100",
+ " final_score: 50",
+ " initial_score: 50",
+ " ip_support: 2",
" no_default_network_duration_ms: 0",
- " previous_network_id <",
- " network_id: 100",
- " >",
- " previous_network_ip_support: 2",
- " transport_types: 1",
+ " previous_default_network_link_layer: 0",
+ " previous_network_ip_support: 0",
+ " validation_duration_ms: 100",
" >",
">",
"events <",
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index 6723601..83194d9 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -82,9 +82,8 @@
public void testWakeupEventLogging() throws Exception {
final int BUFFER_LENGTH = NetdEventListenerService.WAKEUP_EVENT_BUFFER_LENGTH;
- // Assert no events
- String[] events1 = listNetdEvent();
- assertEquals(new String[]{""}, events1);
+ // Baseline without any event
+ String[] baseline = listNetdEvent();
long now = System.currentTimeMillis();
String prefix = "iface:wlan0";
@@ -93,7 +92,7 @@
mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
}
- String[] events2 = listNetdEvent();
+ String[] events2 = remove(listNetdEvent(), baseline);
int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line
assertEquals(expectedLength2, events2.length);
assertContains(events2[0], "WakeupStats");
@@ -111,7 +110,7 @@
mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, ts);
}
- String[] events3 = listNetdEvent();
+ String[] events3 = remove(listNetdEvent(), baseline);
int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line
assertEquals(expectedLength3, events3.length);
assertContains(events2[0], "WakeupStats");
@@ -126,7 +125,7 @@
uid = 45678;
mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
- String[] events4 = listNetdEvent();
+ String[] events4 = remove(listNetdEvent(), baseline);
String lastEvent = events4[events4.length - 1];
assertContains(lastEvent, "WakeupEvent");
assertContains(lastEvent, "wlan0");
@@ -423,7 +422,7 @@
final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
new Thread(() -> {
while (System.currentTimeMillis() < stop) {
- mNetdEventListenerService.dump(pw);
+ mNetdEventListenerService.list(pw);
}
}).start();
}
@@ -461,4 +460,16 @@
static void assertContains(String got, String want) {
assertTrue(got + " did not contain \"" + want + "\"", got.contains(want));
}
+
+ static <T> T[] remove(T[] array, T[] filtered) {
+ List<T> c = Arrays.asList(filtered);
+ int next = 0;
+ for (int i = 0; i < array.length; i++) {
+ if (c.contains(array[i])) {
+ continue;
+ }
+ array[next++] = array[i];
+ }
+ return Arrays.copyOf(array, next);
+ }
}
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index fe396c3..c29363c 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -20,11 +20,30 @@
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.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
+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_ROAMING;
+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.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.AdditionalMatchers.*;
-import static org.mockito.Mockito.*;
+import static org.mockito.AdditionalMatchers.aryEq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
@@ -36,6 +55,9 @@
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
import android.net.UidRange;
import android.net.VpnService;
@@ -45,17 +67,17 @@
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
-import android.support.test.runner.AndroidJUnit4;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.util.ArrayMap;
import android.util.ArraySet;
import com.android.internal.R;
import com.android.internal.net.VpnConfig;
-import org.junit.runner.RunWith;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.InOrder;
import org.mockito.Mock;
@@ -64,6 +86,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -114,6 +137,7 @@
@Mock private AppOpsManager mAppOps;
@Mock private NotificationManager mNotificationManager;
@Mock private Vpn.SystemServices mSystemServices;
+ @Mock private ConnectivityManager mConnectivityManager;
@Before
public void setUp() throws Exception {
@@ -127,6 +151,8 @@
when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
.thenReturn(mNotificationManager);
+ when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE)))
+ .thenReturn(mConnectivityManager);
when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent))
.thenReturn(Resources.getSystem().getString(
R.string.config_customVpnAlwaysOnDisconnectedDialogComponent));
@@ -397,6 +423,66 @@
order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
}
+ @Test
+ public void testCapabilities() {
+ final Vpn vpn = createVpn(primaryUser.id);
+ 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_METERED)
+ .setLinkDownstreamBandwidthKbps(10));
+ networks.put(wifi, new NetworkCapabilities()
+ .addTransportType(TRANSPORT_WIFI)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_ROAMING)
+ .setLinkUpstreamBandwidthKbps(20));
+ setMockedNetworks(networks);
+
+ final NetworkCapabilities caps = new NetworkCapabilities();
+
+ Vpn.updateCapabilities(mConnectivityManager, new Network[] { }, caps);
+ 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));
+
+ Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile }, caps);
+ 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());
+ assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
+ assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+
+ Vpn.updateCapabilities(mConnectivityManager, new Network[] { wifi }, caps);
+ 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));
+
+ Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile, wifi }, caps);
+ 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));
+ }
+
/**
* Mock some methods of vpn object.
*/
@@ -463,4 +549,11 @@
} catch (Exception e) {
}
}
+
+ private void setMockedNetworks(final Map<Network, NetworkCapabilities> networks) {
+ doAnswer(invocation -> {
+ final Network network = (Network) invocation.getArguments()[0];
+ return networks.get(network);
+ }).when(mConnectivityManager).getNetworkCapabilities(any());
+ }
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index fa99795..375b418 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -1169,9 +1169,8 @@
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
final NetworkCapabilities capabilities = new NetworkCapabilities();
- if (!isMetered) {
- capabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- }
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
return new NetworkState(info, prop, capabilities, null, null, TEST_SSID);
}
@@ -1187,6 +1186,8 @@
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
final NetworkCapabilities capabilities = new NetworkCapabilities();
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
return new NetworkState(info, prop, capabilities, null, subscriberId, null);
}
@@ -1196,6 +1197,8 @@
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(iface);
final NetworkCapabilities capabilities = new NetworkCapabilities();
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
return new NetworkState(info, prop, capabilities, null, null, null);
}