Allow network transport type override
Bug: b/112588045
Test: atest EthernetServiceTests --verbose
Test: kitchensink with RPi devices connected by USB -> Ethernet
adapters. Edit config.xml to try different tranport
overrides manually. Use dumpsys ethernet to show final
final network scores.
Change-Id: I482e78a76d06c9c090aa6816db14bb346eb6528b
This commit is contained in:
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package com.android.server.ethernet;
|
package com.android.server.ethernet;
|
||||||
|
|
||||||
import static android.net.ConnectivityManager.TYPE_ETHERNET;
|
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
import android.net.IpConfiguration;
|
import android.net.IpConfiguration;
|
||||||
import android.net.IpConfiguration.IpAssignment;
|
import android.net.IpConfiguration.IpAssignment;
|
||||||
import android.net.IpConfiguration.ProxySettings;
|
import android.net.IpConfiguration.ProxySettings;
|
||||||
@@ -37,10 +39,12 @@ import android.net.util.InterfaceParams;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.lang.Math;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,6 +243,52 @@ public class EthernetNetworkFactory extends NetworkFactory {
|
|||||||
private NetworkAgent mNetworkAgent;
|
private NetworkAgent mNetworkAgent;
|
||||||
private IpConfiguration mIpConfig;
|
private IpConfiguration mIpConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object to contain all transport type information, including base network score and
|
||||||
|
* the legacy transport type it maps to (if any)
|
||||||
|
*/
|
||||||
|
private static class TransportInfo {
|
||||||
|
final int mLegacyType;
|
||||||
|
final int mScore;
|
||||||
|
|
||||||
|
private TransportInfo(int legacyType, int score) {
|
||||||
|
mLegacyType = legacyType;
|
||||||
|
mScore = score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of TRANSPORT_* types to TransportInfo, making scoring and legacy type information
|
||||||
|
* available for each type an ethernet interface could propagate.
|
||||||
|
*
|
||||||
|
* Unfortunately, base scores for the various transports are not yet centrally located.
|
||||||
|
* They've been lifted from the corresponding NetworkFactory files in the meantime.
|
||||||
|
*
|
||||||
|
* Additionally, there are no legacy type equivalents to LOWPAN or WIFI_AWARE. These types
|
||||||
|
* are set to TYPE_NONE to match the behavior of their own network factories.
|
||||||
|
*/
|
||||||
|
private static final SparseArray<TransportInfo> sTransports = new SparseArray();
|
||||||
|
static {
|
||||||
|
// LowpanInterfaceTracker.NETWORK_SCORE
|
||||||
|
sTransports.put(NetworkCapabilities.TRANSPORT_LOWPAN,
|
||||||
|
new TransportInfo(ConnectivityManager.TYPE_NONE, 30));
|
||||||
|
// WifiAwareDataPathStateManager.NETWORK_FACTORY_SCORE_AVAIL
|
||||||
|
sTransports.put(NetworkCapabilities.TRANSPORT_WIFI_AWARE,
|
||||||
|
new TransportInfo(ConnectivityManager.TYPE_NONE, 1));
|
||||||
|
// EthernetNetworkFactory.NETWORK_SCORE
|
||||||
|
sTransports.put(NetworkCapabilities.TRANSPORT_ETHERNET,
|
||||||
|
new TransportInfo(ConnectivityManager.TYPE_ETHERNET, 70));
|
||||||
|
// BluetoothTetheringNetworkFactory.NETWORK_SCORE
|
||||||
|
sTransports.put(NetworkCapabilities.TRANSPORT_BLUETOOTH,
|
||||||
|
new TransportInfo(ConnectivityManager.TYPE_BLUETOOTH, 69));
|
||||||
|
// WifiNetworkFactory.SCORE_FILTER / NetworkAgent.WIFI_BASE_SCORE
|
||||||
|
sTransports.put(NetworkCapabilities.TRANSPORT_WIFI,
|
||||||
|
new TransportInfo(ConnectivityManager.TYPE_WIFI, 60));
|
||||||
|
// TelephonyNetworkFactory.TELEPHONY_NETWORK_SCORE
|
||||||
|
sTransports.put(NetworkCapabilities.TRANSPORT_CELLULAR,
|
||||||
|
new TransportInfo(ConnectivityManager.TYPE_MOBILE, 50));
|
||||||
|
}
|
||||||
|
|
||||||
long refCount = 0;
|
long refCount = 0;
|
||||||
|
|
||||||
private final IpClient.Callback mIpClientCallback = new IpClient.Callback() {
|
private final IpClient.Callback mIpClientCallback = new IpClient.Callback() {
|
||||||
@@ -259,14 +309,23 @@ public class EthernetNetworkFactory extends NetworkFactory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
NetworkInterfaceState(String ifaceName, String hwAddress, Handler handler, Context context,
|
NetworkInterfaceState(String ifaceName, String hwAddress, Handler handler, Context context,
|
||||||
NetworkCapabilities capabilities) {
|
@NonNull NetworkCapabilities capabilities) {
|
||||||
name = ifaceName;
|
name = ifaceName;
|
||||||
mCapabilities = capabilities;
|
mCapabilities = checkNotNull(capabilities);
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
int legacyType = ConnectivityManager.TYPE_NONE;
|
||||||
|
int[] transportTypes = mCapabilities.getTransportTypes();
|
||||||
|
if (transportTypes.length > 0) {
|
||||||
|
legacyType = getLegacyType(transportTypes[0]);
|
||||||
|
} else {
|
||||||
|
// Should never happen as transport is always one of ETHERNET or a valid override
|
||||||
|
Log.w(TAG, "There is no transport type associated with network interface '"
|
||||||
|
+ mLinkProperties.getInterfaceName() + "' -- Legacy type set to TYPE_NONE");
|
||||||
|
}
|
||||||
|
|
||||||
mHwAddress = hwAddress;
|
mHwAddress = hwAddress;
|
||||||
mNetworkInfo = new NetworkInfo(TYPE_ETHERNET, 0, NETWORK_TYPE, "");
|
mNetworkInfo = new NetworkInfo(legacyType, 0, NETWORK_TYPE, "");
|
||||||
mNetworkInfo.setExtraInfo(mHwAddress);
|
mNetworkInfo.setExtraInfo(mHwAddress);
|
||||||
mNetworkInfo.setIsAvailable(true);
|
mNetworkInfo.setIsAvailable(true);
|
||||||
}
|
}
|
||||||
@@ -283,6 +342,47 @@ public class EthernetNetworkFactory extends NetworkFactory {
|
|||||||
return mCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
|
return mCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the legacy transport type from a NetworkCapabilities transport type. Defaults
|
||||||
|
* to legacy TYPE_NONE if there is no known conversion
|
||||||
|
*/
|
||||||
|
private static int getLegacyType(int transport) {
|
||||||
|
TransportInfo transportInfo = sTransports.get(transport, /* if dne */ null);
|
||||||
|
if (transportInfo != null) {
|
||||||
|
return transportInfo.mLegacyType;
|
||||||
|
}
|
||||||
|
return ConnectivityManager.TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the network score based on the transport associated with the interface.
|
||||||
|
* Ethernet interfaces could propagate a transport types forward. Since we can't
|
||||||
|
* get more information about the statuses of the interfaces on the other end of the local
|
||||||
|
* interface, we'll best-effort assign the score as the base score of the assigned transport
|
||||||
|
* when the link is up. When the link is down, the score is set to zero.
|
||||||
|
*
|
||||||
|
* This function is called with the purpose of assigning and updating the network score of
|
||||||
|
* the member NetworkAgent.
|
||||||
|
*/
|
||||||
|
private int getNetworkScore() {
|
||||||
|
// never set the network score below 0.
|
||||||
|
if (!mLinkUp) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] transportTypes = mCapabilities.getTransportTypes();
|
||||||
|
if (transportTypes.length < 1) {
|
||||||
|
Log.w(TAG, "There is no transport type associated with network interface '"
|
||||||
|
+ mLinkProperties.getInterfaceName() + "' -- Score set to zero");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
TransportInfo transportInfo = sTransports.get(transportTypes[0], /* if dne */ null);
|
||||||
|
if (transportInfo != null) {
|
||||||
|
return transportInfo.mScore;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private void start() {
|
private void start() {
|
||||||
if (mIpClient != null) {
|
if (mIpClient != null) {
|
||||||
if (DBG) Log.d(TAG, "IpClient already started");
|
if (DBG) Log.d(TAG, "IpClient already started");
|
||||||
@@ -317,7 +417,7 @@ public class EthernetNetworkFactory extends NetworkFactory {
|
|||||||
// Create our NetworkAgent.
|
// Create our NetworkAgent.
|
||||||
mNetworkAgent = new NetworkAgent(mHandler.getLooper(), mContext,
|
mNetworkAgent = new NetworkAgent(mHandler.getLooper(), mContext,
|
||||||
NETWORK_TYPE, mNetworkInfo, mCapabilities, mLinkProperties,
|
NETWORK_TYPE, mNetworkInfo, mCapabilities, mLinkProperties,
|
||||||
NETWORK_SCORE) {
|
getNetworkScore()) {
|
||||||
public void unwanted() {
|
public void unwanted() {
|
||||||
if (this == mNetworkAgent) {
|
if (this == mNetworkAgent) {
|
||||||
stop();
|
stop();
|
||||||
@@ -390,8 +490,11 @@ public class EthernetNetworkFactory extends NetworkFactory {
|
|||||||
mNetworkAgent.sendNetworkCapabilities(mCapabilities);
|
mNetworkAgent.sendNetworkCapabilities(mCapabilities);
|
||||||
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
|
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
|
||||||
mNetworkAgent.sendLinkProperties(mLinkProperties);
|
mNetworkAgent.sendLinkProperties(mLinkProperties);
|
||||||
// never set the network score below 0.
|
|
||||||
mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);
|
// As a note, getNetworkScore() is fairly expensive to calculate. This is fine for now
|
||||||
|
// since the agent isn't update frequently. Consider caching the score in the future if
|
||||||
|
// agent updating is required more often
|
||||||
|
mNetworkAgent.sendNetworkScore(getNetworkScore());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clear() {
|
private void clear() {
|
||||||
@@ -433,7 +536,9 @@ public class EthernetNetworkFactory extends NetworkFactory {
|
|||||||
+ "up: " + mLinkUp + ", "
|
+ "up: " + mLinkUp + ", "
|
||||||
+ "hwAddress: " + mHwAddress + ", "
|
+ "hwAddress: " + mHwAddress + ", "
|
||||||
+ "networkInfo: " + mNetworkInfo + ", "
|
+ "networkInfo: " + mNetworkInfo + ", "
|
||||||
|
+ "networkCapabilities: " + mCapabilities + ", "
|
||||||
+ "networkAgent: " + mNetworkAgent + ", "
|
+ "networkAgent: " + mNetworkAgent + ", "
|
||||||
|
+ "score: " + getNetworkScore() + ", "
|
||||||
+ "ipClient: " + mIpClient + ","
|
+ "ipClient: " + mIpClient + ","
|
||||||
+ "linkProperties: " + mLinkProperties
|
+ "linkProperties: " + mLinkProperties
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|||||||
@@ -294,12 +294,20 @@ final class EthernetTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an Ethernet interface configuration
|
||||||
|
*
|
||||||
|
* @param configString represents an Ethernet configuration in the following format: {@code
|
||||||
|
* <interface name|mac address>;[Network Capabilities];[IP config];[Override Transport]}
|
||||||
|
*/
|
||||||
private void parseEthernetConfig(String configString) {
|
private void parseEthernetConfig(String configString) {
|
||||||
String[] tokens = configString.split(";");
|
String[] tokens = configString.split(";", /* limit of tokens */ 4);
|
||||||
String name = tokens[0];
|
String name = tokens[0];
|
||||||
String capabilities = tokens.length > 1 ? tokens[1] : null;
|
String capabilities = tokens.length > 1 ? tokens[1] : null;
|
||||||
|
String transport = tokens.length > 3 ? tokens[3] : null;
|
||||||
NetworkCapabilities nc = createNetworkCapabilities(
|
NetworkCapabilities nc = createNetworkCapabilities(
|
||||||
!TextUtils.isEmpty(capabilities) /* clear default capabilities */, capabilities);
|
!TextUtils.isEmpty(capabilities) /* clear default capabilities */, capabilities,
|
||||||
|
transport);
|
||||||
mNetworkCapabilities.put(name, nc);
|
mNetworkCapabilities.put(name, nc);
|
||||||
|
|
||||||
if (tokens.length > 2 && !TextUtils.isEmpty(tokens[2])) {
|
if (tokens.length > 2 && !TextUtils.isEmpty(tokens[2])) {
|
||||||
@@ -320,24 +328,76 @@ final class EthernetTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkCapabilities createNetworkCapabilities(boolean clearDefaultCapabilities) {
|
private static NetworkCapabilities createNetworkCapabilities(boolean clearDefaultCapabilities) {
|
||||||
return createNetworkCapabilities(clearDefaultCapabilities, null);
|
return createNetworkCapabilities(clearDefaultCapabilities, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkCapabilities createNetworkCapabilities(
|
/**
|
||||||
boolean clearDefaultCapabilities, @Nullable String commaSeparatedCapabilities) {
|
* Parses a static list of network capabilities
|
||||||
|
*
|
||||||
|
* @param clearDefaultCapabilities Indicates whether or not to clear any default capabilities
|
||||||
|
* @param commaSeparatedCapabilities A comma separated string list of integer encoded
|
||||||
|
* NetworkCapability.NET_CAPABILITY_* values
|
||||||
|
* @param overrideTransport A string representing a single override transport type, must be one
|
||||||
|
* of the NetworkCapability.TRANSPORT_* values. TRANSPORT_VPN is
|
||||||
|
* not supported. Errors with input will cause the override to
|
||||||
|
* be ignored.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
static NetworkCapabilities createNetworkCapabilities(
|
||||||
|
boolean clearDefaultCapabilities, @Nullable String commaSeparatedCapabilities,
|
||||||
|
@Nullable String overrideTransport) {
|
||||||
|
|
||||||
NetworkCapabilities nc = new NetworkCapabilities();
|
NetworkCapabilities nc = new NetworkCapabilities();
|
||||||
if (clearDefaultCapabilities) {
|
if (clearDefaultCapabilities) {
|
||||||
nc.clearAll(); // Remove default capabilities.
|
nc.clearAll(); // Remove default capabilities and transports
|
||||||
}
|
}
|
||||||
nc.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET);
|
|
||||||
|
// Determine the transport type. If someone has tried to define an override transport then
|
||||||
|
// attempt to add it. Since we can only have one override, all errors with it will
|
||||||
|
// gracefully default back to TRANSPORT_ETHERNET and warn the user. VPN is not allowed as an
|
||||||
|
// override type. Wifi Aware and LoWPAN are currently unsupported as well.
|
||||||
|
int transport = NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||||
|
if (!TextUtils.isEmpty(overrideTransport)) {
|
||||||
|
try {
|
||||||
|
int parsedTransport = Integer.valueOf(overrideTransport);
|
||||||
|
if (parsedTransport == NetworkCapabilities.TRANSPORT_VPN
|
||||||
|
|| parsedTransport == NetworkCapabilities.TRANSPORT_WIFI_AWARE
|
||||||
|
|| parsedTransport == NetworkCapabilities.TRANSPORT_LOWPAN) {
|
||||||
|
Log.e(TAG, "Override transport '" + parsedTransport + "' is not supported -- "
|
||||||
|
+ "Defaulting to TRANSPORT_ETHERNET");
|
||||||
|
} else {
|
||||||
|
transport = parsedTransport;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
Log.e(TAG, "Override transport type '" + overrideTransport + "' could not be parsed"
|
||||||
|
+ "-- Defaulting to TRANSPORT_ETHERNET");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the transport. If the user supplied a valid number that is not a valid transport
|
||||||
|
// then adding will throw an exception. Default back to TRANSPORT_ETHERNET if that happens
|
||||||
|
try {
|
||||||
|
nc.addTransportType(transport);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
Log.e(TAG, transport + " is not a valid NetworkCapability.TRANSPORT_* value"
|
||||||
|
+ " -- Defaulting to TRANSPORT_ETHERNET");
|
||||||
|
nc.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET);
|
||||||
|
}
|
||||||
|
|
||||||
nc.setLinkUpstreamBandwidthKbps(100 * 1000);
|
nc.setLinkUpstreamBandwidthKbps(100 * 1000);
|
||||||
nc.setLinkDownstreamBandwidthKbps(100 * 1000);
|
nc.setLinkDownstreamBandwidthKbps(100 * 1000);
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(commaSeparatedCapabilities)) {
|
if (!TextUtils.isEmpty(commaSeparatedCapabilities)) {
|
||||||
for (String strNetworkCapability : commaSeparatedCapabilities.split(",")) {
|
for (String strNetworkCapability : commaSeparatedCapabilities.split(",")) {
|
||||||
if (!TextUtils.isEmpty(strNetworkCapability)) {
|
if (!TextUtils.isEmpty(strNetworkCapability)) {
|
||||||
nc.addCapability(Integer.valueOf(strNetworkCapability));
|
try {
|
||||||
|
nc.addCapability(Integer.valueOf(strNetworkCapability));
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
Log.e(TAG, "Capability '" + strNetworkCapability + "' could not be parsed");
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
Log.e(TAG, strNetworkCapability + " is not a valid "
|
||||||
|
+ "NetworkCapability.NET_CAPABILITY_* value");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.net.IpConfiguration;
|
|||||||
import android.net.IpConfiguration.IpAssignment;
|
import android.net.IpConfiguration.IpAssignment;
|
||||||
import android.net.IpConfiguration.ProxySettings;
|
import android.net.IpConfiguration.ProxySettings;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.StaticIpConfiguration;
|
import android.net.StaticIpConfiguration;
|
||||||
import android.support.test.filters.SmallTest;
|
import android.support.test.filters.SmallTest;
|
||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
@@ -35,47 +36,55 @@ import java.net.InetAddress;
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class EthernetTrackerTest {
|
public class EthernetTrackerTest {
|
||||||
|
/**
|
||||||
|
* Test: Creation of various valid static IP configurations
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void createStaticIpConfiguration() {
|
public void createStaticIpConfiguration() {
|
||||||
assertStaticConfiguration("", new StaticIpConfiguration());
|
// Empty gives default StaticIPConfiguration object
|
||||||
|
assertStaticConfiguration(new StaticIpConfiguration(), "");
|
||||||
|
|
||||||
|
// Setting only the IP address properly cascades and assumes defaults
|
||||||
assertStaticConfiguration(
|
assertStaticConfiguration(
|
||||||
"ip=192.0.2.10/24",
|
new StaticIpConfigBuilder().setIp("192.0.2.10/24").build(),
|
||||||
new StaticIpConfigBuilder().setIp("192.0.2.10/24").build());
|
"ip=192.0.2.10/24");
|
||||||
|
|
||||||
|
// Setting other fields properly cascades them
|
||||||
assertStaticConfiguration(
|
assertStaticConfiguration(
|
||||||
"ip=192.0.2.10/24 dns=4.4.4.4,8.8.8.8 gateway=192.0.2.1 domains=android",
|
|
||||||
new StaticIpConfigBuilder()
|
new StaticIpConfigBuilder()
|
||||||
.setIp("192.0.2.10/24")
|
.setIp("192.0.2.10/24")
|
||||||
.setDns(new String[] {"4.4.4.4", "8.8.8.8"})
|
.setDns(new String[] {"4.4.4.4", "8.8.8.8"})
|
||||||
.setGateway("192.0.2.1")
|
.setGateway("192.0.2.1")
|
||||||
.setDomains("android")
|
.setDomains("android")
|
||||||
.build());
|
.build(),
|
||||||
|
"ip=192.0.2.10/24 dns=4.4.4.4,8.8.8.8 gateway=192.0.2.1 domains=android");
|
||||||
|
|
||||||
// Verify order doesn't matter
|
// Verify order doesn't matter
|
||||||
assertStaticConfiguration(
|
assertStaticConfiguration(
|
||||||
"domains=android ip=192.0.2.10/24 gateway=192.0.2.1 dns=4.4.4.4,8.8.8.8 ",
|
|
||||||
new StaticIpConfigBuilder()
|
new StaticIpConfigBuilder()
|
||||||
.setIp("192.0.2.10/24")
|
.setIp("192.0.2.10/24")
|
||||||
.setDns(new String[] {"4.4.4.4", "8.8.8.8"})
|
.setDns(new String[] {"4.4.4.4", "8.8.8.8"})
|
||||||
.setGateway("192.0.2.1")
|
.setGateway("192.0.2.1")
|
||||||
.setDomains("android")
|
.setDomains("android")
|
||||||
.build());
|
.build(),
|
||||||
|
"domains=android ip=192.0.2.10/24 gateway=192.0.2.1 dns=4.4.4.4,8.8.8.8 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test: Attempt creation of various bad static IP configurations
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void createStaticIpConfiguration_Bad() {
|
public void createStaticIpConfiguration_Bad() {
|
||||||
assertFails("ip=192.0.2.1/24 gateway= blah=20.20.20.20"); // Unknown key
|
assertStaticConfigurationFails("ip=192.0.2.1/24 gateway= blah=20.20.20.20"); // Unknown key
|
||||||
assertFails("ip=192.0.2.1"); // mask is missing
|
assertStaticConfigurationFails("ip=192.0.2.1"); // mask is missing
|
||||||
assertFails("ip=a.b.c"); // not a valid ip address
|
assertStaticConfigurationFails("ip=a.b.c"); // not a valid ip address
|
||||||
assertFails("dns=4.4.4.4,1.2.3.A"); // not valid ip address in dns
|
assertStaticConfigurationFails("dns=4.4.4.4,1.2.3.A"); // not valid ip address in dns
|
||||||
assertFails("="); // Key and value is empty
|
assertStaticConfigurationFails("="); // Key and value is empty
|
||||||
assertFails("ip="); // Value is empty
|
assertStaticConfigurationFails("ip="); // Value is empty
|
||||||
assertFails("ip=192.0.2.1/24 gateway="); // Gateway is empty
|
assertStaticConfigurationFails("ip=192.0.2.1/24 gateway="); // Gateway is empty
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertFails(String config) {
|
private void assertStaticConfigurationFails(String config) {
|
||||||
try {
|
try {
|
||||||
EthernetTracker.parseStaticIpConfiguration(config);
|
EthernetTracker.parseStaticIpConfiguration(config);
|
||||||
fail("Expected to fail: " + config);
|
fail("Expected to fail: " + config);
|
||||||
@@ -84,8 +93,8 @@ public class EthernetTrackerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertStaticConfiguration(String configAsString,
|
private void assertStaticConfiguration(StaticIpConfiguration expectedStaticIpConfig,
|
||||||
StaticIpConfiguration expectedStaticIpConfig) {
|
String configAsString) {
|
||||||
IpConfiguration expectedIpConfiguration = new IpConfiguration(IpAssignment.STATIC,
|
IpConfiguration expectedIpConfiguration = new IpConfiguration(IpAssignment.STATIC,
|
||||||
ProxySettings.NONE, expectedStaticIpConfig, null);
|
ProxySettings.NONE, expectedStaticIpConfig, null);
|
||||||
|
|
||||||
@@ -118,9 +127,178 @@ public class EthernetTrackerTest {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StaticIpConfiguration build() {
|
StaticIpConfiguration build() {
|
||||||
return new StaticIpConfiguration(config);
|
return new StaticIpConfiguration(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test: Attempt to create a capabilties with various valid sets of capabilities/transports
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void createNetworkCapabilities() {
|
||||||
|
|
||||||
|
// Particularly common expected results
|
||||||
|
NetworkCapabilities defaultEthernetCleared = new NetworkCapabilitiesBuilder()
|
||||||
|
.clearAll()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
NetworkCapabilities ethernetClearedWithCommonCaps = new NetworkCapabilitiesBuilder()
|
||||||
|
.clearAll()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
|
||||||
|
.addCapability(12)
|
||||||
|
.addCapability(13)
|
||||||
|
.addCapability(14)
|
||||||
|
.addCapability(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Empty capabilities and transports lists with a "please clear defaults" should
|
||||||
|
// yield an empty capabilities set with TRANPORT_ETHERNET
|
||||||
|
assertNetworkCapabilities(defaultEthernetCleared, true, "", "");
|
||||||
|
|
||||||
|
// Empty capabilities and transports without the clear defaults flag should return the
|
||||||
|
// default capabilities set with TRANSPORT_ETHERNET
|
||||||
|
assertNetworkCapabilities(
|
||||||
|
new NetworkCapabilitiesBuilder()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
|
||||||
|
.build(),
|
||||||
|
false, "", "");
|
||||||
|
|
||||||
|
// A list of capabilities without the clear defaults flag should return the default
|
||||||
|
// capabilities, mixed with the desired capabilities, and TRANSPORT_ETHERNET
|
||||||
|
assertNetworkCapabilities(
|
||||||
|
new NetworkCapabilitiesBuilder()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
|
||||||
|
.addCapability(11)
|
||||||
|
.addCapability(12)
|
||||||
|
.build(),
|
||||||
|
false, "11,12", "");
|
||||||
|
|
||||||
|
// Adding a list of capabilities with a clear defaults will leave exactly those capabilities
|
||||||
|
// with a default TRANSPORT_ETHERNET since no overrides are specified
|
||||||
|
assertNetworkCapabilities(ethernetClearedWithCommonCaps, true, "12,13,14,15", "");
|
||||||
|
|
||||||
|
// Adding any invalid capabilities to the list will cause them to be ignored
|
||||||
|
assertNetworkCapabilities(ethernetClearedWithCommonCaps, true, "12,13,14,15,65,73", "");
|
||||||
|
assertNetworkCapabilities(ethernetClearedWithCommonCaps, true, "12,13,14,15,abcdefg", "");
|
||||||
|
|
||||||
|
// Adding a valid override transport will remove the default TRANSPORT_ETHERNET transport
|
||||||
|
// and apply only the override to the capabiltities object
|
||||||
|
assertNetworkCapabilities(
|
||||||
|
new NetworkCapabilitiesBuilder()
|
||||||
|
.clearAll()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(0)
|
||||||
|
.build(),
|
||||||
|
true, "", "0");
|
||||||
|
assertNetworkCapabilities(
|
||||||
|
new NetworkCapabilitiesBuilder()
|
||||||
|
.clearAll()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(1)
|
||||||
|
.build(),
|
||||||
|
true, "", "1");
|
||||||
|
assertNetworkCapabilities(
|
||||||
|
new NetworkCapabilitiesBuilder()
|
||||||
|
.clearAll()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(2)
|
||||||
|
.build(),
|
||||||
|
true, "", "2");
|
||||||
|
assertNetworkCapabilities(
|
||||||
|
new NetworkCapabilitiesBuilder()
|
||||||
|
.clearAll()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addTransport(3)
|
||||||
|
.build(),
|
||||||
|
true, "", "3");
|
||||||
|
|
||||||
|
// "4" is TRANSPORT_VPN, which is unsupported. Should default back to TRANPORT_ETHERNET
|
||||||
|
assertNetworkCapabilities(defaultEthernetCleared, true, "", "4");
|
||||||
|
|
||||||
|
// "5" is TRANSPORT_WIFI_AWARE, which is currently supported due to no legacy TYPE_NONE
|
||||||
|
// conversion. When that becomes available, this test must be updated
|
||||||
|
assertNetworkCapabilities(defaultEthernetCleared, true, "", "5");
|
||||||
|
|
||||||
|
// "6" is TRANSPORT_LOWPAN, which is currently supported due to no legacy TYPE_NONE
|
||||||
|
// conversion. When that becomes available, this test must be updated
|
||||||
|
assertNetworkCapabilities(defaultEthernetCleared, true, "", "6");
|
||||||
|
|
||||||
|
// Adding an invalid override transport will leave the transport as TRANSPORT_ETHERNET
|
||||||
|
assertNetworkCapabilities(defaultEthernetCleared,true, "", "100");
|
||||||
|
assertNetworkCapabilities(defaultEthernetCleared, true, "", "abcdefg");
|
||||||
|
|
||||||
|
// Ensure the adding of both capabilities and transports work
|
||||||
|
assertNetworkCapabilities(
|
||||||
|
new NetworkCapabilitiesBuilder()
|
||||||
|
.clearAll()
|
||||||
|
.setLinkUpstreamBandwidthKbps(100000)
|
||||||
|
.setLinkDownstreamBandwidthKbps(100000)
|
||||||
|
.addCapability(12)
|
||||||
|
.addCapability(13)
|
||||||
|
.addCapability(14)
|
||||||
|
.addCapability(15)
|
||||||
|
.addTransport(3)
|
||||||
|
.build(),
|
||||||
|
true, "12,13,14,15", "3");
|
||||||
|
|
||||||
|
// Ensure order does not matter for capability list
|
||||||
|
assertNetworkCapabilities(ethernetClearedWithCommonCaps, true, "13,12,15,14", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNetworkCapabilities(NetworkCapabilities expectedNetworkCapabilities,
|
||||||
|
boolean clearCapabilties, String configCapabiltiies,String configTransports) {
|
||||||
|
assertEquals(expectedNetworkCapabilities,
|
||||||
|
EthernetTracker.createNetworkCapabilities(clearCapabilties, configCapabiltiies,
|
||||||
|
configTransports));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NetworkCapabilitiesBuilder {
|
||||||
|
private final NetworkCapabilities nc = new NetworkCapabilities();
|
||||||
|
|
||||||
|
NetworkCapabilitiesBuilder clearAll(){
|
||||||
|
// This is THE ONLY one that doesn't return a reference to the object so I wrapped
|
||||||
|
// everything in a builder to keep things consistent and clean above. Fix if this
|
||||||
|
// ever changes
|
||||||
|
nc.clearAll();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkCapabilitiesBuilder addCapability(int capability) {
|
||||||
|
nc.addCapability(capability);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkCapabilitiesBuilder addTransport(int transport) {
|
||||||
|
nc.addTransportType(transport);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkCapabilitiesBuilder setLinkUpstreamBandwidthKbps(int upKbps) {
|
||||||
|
nc.setLinkUpstreamBandwidthKbps(upKbps);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkCapabilitiesBuilder setLinkDownstreamBandwidthKbps(int downKbps) {
|
||||||
|
nc.setLinkDownstreamBandwidthKbps(downKbps);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkCapabilities build() {
|
||||||
|
return new NetworkCapabilities(nc);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user