Merge "Switch DHCP server based on global setting"
This commit is contained in:
@@ -1126,7 +1126,9 @@ public class Tethering extends BaseNetworkObserver {
|
||||
}
|
||||
|
||||
public String[] getTetheredDhcpRanges() {
|
||||
return mConfig.dhcpRanges;
|
||||
// TODO: this is only valid for the old DHCP server. Latest search suggests it is only used
|
||||
// by WifiP2pServiceImpl to start dnsmasq: remove/deprecate after migrating callers.
|
||||
return mConfig.legacyDhcpRanges;
|
||||
}
|
||||
|
||||
public String[] getErroredIfaces() {
|
||||
@@ -1297,13 +1299,17 @@ public class Tethering extends BaseNetworkObserver {
|
||||
return false;
|
||||
}
|
||||
// TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
|
||||
// Legacy DHCP server is disabled if passed an empty ranges array
|
||||
final String[] dhcpRanges = cfg.enableLegacyDhcpServer
|
||||
? cfg.legacyDhcpRanges
|
||||
: new String[0];
|
||||
try {
|
||||
// TODO: Find a more accurate method name (startDHCPv4()?).
|
||||
mNMService.startTethering(cfg.dhcpRanges);
|
||||
mNMService.startTethering(dhcpRanges);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
mNMService.stopTethering();
|
||||
mNMService.startTethering(cfg.dhcpRanges);
|
||||
mNMService.startTethering(dhcpRanges);
|
||||
} catch (Exception ee) {
|
||||
mLog.e(ee);
|
||||
transitionTo(mStartTetheringErrorState);
|
||||
@@ -1972,7 +1978,7 @@ public class Tethering extends BaseNetworkObserver {
|
||||
final TetherState tetherState = new TetherState(
|
||||
new TetherInterfaceStateMachine(
|
||||
iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
|
||||
makeControlCallback(iface), mDeps));
|
||||
makeControlCallback(iface), mConfig.enableLegacyDhcpServer, mDeps));
|
||||
mTetherStates.put(iface, tetherState);
|
||||
tetherState.stateMachine.start();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.connectivity.tethering;
|
||||
|
||||
import static android.net.NetworkUtils.numericToInetAddress;
|
||||
import static android.net.util.NetworkConstants.asByte;
|
||||
import static android.net.util.NetworkConstants.FF;
|
||||
import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
|
||||
@@ -27,8 +28,9 @@ import android.net.InterfaceConfiguration;
|
||||
import android.net.IpPrefix;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkUtils;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.dhcp.DhcpServer;
|
||||
import android.net.dhcp.DhcpServingParams;
|
||||
import android.net.ip.InterfaceController;
|
||||
import android.net.ip.RouterAdvertisementDaemon;
|
||||
import android.net.ip.RouterAdvertisementDaemon.RaParams;
|
||||
@@ -49,6 +51,7 @@ import com.android.internal.util.Protocol;
|
||||
import com.android.internal.util.State;
|
||||
import com.android.internal.util.StateMachine;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -73,6 +76,13 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
private static final String WIFI_HOST_IFACE_ADDR = "192.168.43.1";
|
||||
private static final int WIFI_HOST_IFACE_PREFIX_LENGTH = 24;
|
||||
|
||||
// TODO: have PanService use some visible version of this constant
|
||||
private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1";
|
||||
private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
|
||||
|
||||
// TODO: have this configurable
|
||||
private static final int DHCP_LEASE_TIME_SECS = 3600;
|
||||
|
||||
private final static String TAG = "TetherInterfaceSM";
|
||||
private final static boolean DBG = false;
|
||||
private final static boolean VDBG = false;
|
||||
@@ -119,6 +129,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
private final String mIfaceName;
|
||||
private final int mInterfaceType;
|
||||
private final LinkProperties mLinkProperties;
|
||||
private final boolean mUsingLegacyDhcp;
|
||||
|
||||
private final TetheringDependencies mDeps;
|
||||
|
||||
@@ -134,12 +145,13 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
// Advertisements (otherwise, we do not add them to mLinkProperties at all).
|
||||
private LinkProperties mLastIPv6LinkProperties;
|
||||
private RouterAdvertisementDaemon mRaDaemon;
|
||||
private DhcpServer mDhcpServer;
|
||||
private RaParams mLastRaParams;
|
||||
|
||||
public TetherInterfaceStateMachine(
|
||||
String ifaceName, Looper looper, int interfaceType, SharedLog log,
|
||||
INetworkManagementService nMService, INetworkStatsService statsService,
|
||||
IControlsTethering tetherController,
|
||||
IControlsTethering tetherController, boolean usingLegacyDhcp,
|
||||
TetheringDependencies deps) {
|
||||
super(ifaceName, looper);
|
||||
mLog = log.forSubComponent(ifaceName);
|
||||
@@ -151,6 +163,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
mIfaceName = ifaceName;
|
||||
mInterfaceType = interfaceType;
|
||||
mLinkProperties = new LinkProperties();
|
||||
mUsingLegacyDhcp = usingLegacyDhcp;
|
||||
mDeps = deps;
|
||||
resetLinkProperties();
|
||||
mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
|
||||
@@ -188,6 +201,52 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
|
||||
private boolean startIPv4() { return configureIPv4(true); }
|
||||
|
||||
private boolean startDhcp(Inet4Address addr, int prefixLen) {
|
||||
if (mUsingLegacyDhcp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final InterfaceParams ifaceParams = mDeps.getInterfaceParams(mIfaceName);
|
||||
if (ifaceParams == null) {
|
||||
Log.e(TAG, "Failed to find interface params for DHCPv4");
|
||||
return false;
|
||||
}
|
||||
final DhcpServingParams params;
|
||||
try {
|
||||
params = new DhcpServingParams.Builder()
|
||||
.setDefaultRouters(addr)
|
||||
.setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
|
||||
.setDnsServers(addr)
|
||||
.setServerAddr(new LinkAddress(addr, prefixLen))
|
||||
.build();
|
||||
// TODO: also advertise link MTU
|
||||
} catch (DhcpServingParams.InvalidParameterException e) {
|
||||
Log.e(TAG, "Invalid DHCP parameters", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
mDhcpServer = mDeps.makeDhcpServer(getHandler().getLooper(), ifaceParams, params,
|
||||
mLog.forSubComponent("DHCP"));
|
||||
mDhcpServer.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void stopDhcp() {
|
||||
if (mDhcpServer != null) {
|
||||
mDhcpServer.stop();
|
||||
mDhcpServer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean configureDhcp(boolean enable, Inet4Address addr, int prefixLen) {
|
||||
if (enable) {
|
||||
return startDhcp(addr, prefixLen);
|
||||
} else {
|
||||
stopDhcp();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void stopIPv4() {
|
||||
configureIPv4(false);
|
||||
// NOTE: All of configureIPv4() will be refactored out of existence
|
||||
@@ -210,8 +269,9 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
ipAsString = getRandomWifiIPv4Address();
|
||||
prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;
|
||||
} else {
|
||||
// Nothing to do, BT does this elsewhere.
|
||||
return true;
|
||||
// BT configures the interface elsewhere: only start DHCP.
|
||||
final Inet4Address srvAddr = (Inet4Address) numericToInetAddress(BLUETOOTH_IFACE_ADDR);
|
||||
return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
|
||||
}
|
||||
|
||||
final LinkAddress linkAddr;
|
||||
@@ -222,7 +282,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
return false;
|
||||
}
|
||||
|
||||
InetAddress addr = NetworkUtils.numericToInetAddress(ipAsString);
|
||||
InetAddress addr = numericToInetAddress(ipAsString);
|
||||
linkAddr = new LinkAddress(addr, prefixLen);
|
||||
ifcg.setLinkAddress(linkAddr);
|
||||
if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
|
||||
@@ -239,6 +299,10 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
}
|
||||
ifcg.clearFlag("running");
|
||||
mNMService.setInterfaceConfig(mIfaceName, ifcg);
|
||||
|
||||
if (!configureDhcp(enabled, (Inet4Address) addr, prefixLen)) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
mLog.e("Error configuring interface " + e);
|
||||
return false;
|
||||
@@ -258,7 +322,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
|
||||
private String getRandomWifiIPv4Address() {
|
||||
try {
|
||||
byte[] bytes = NetworkUtils.numericToInetAddress(WIFI_HOST_IFACE_ADDR).getAddress();
|
||||
byte[] bytes = numericToInetAddress(WIFI_HOST_IFACE_ADDR).getAddress();
|
||||
bytes[3] = getRandomSanitizedByte(DOUG_ADAMS, asByte(0), asByte(1), FF);
|
||||
return InetAddress.getByAddress(bytes).getHostAddress();
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -21,6 +21,8 @@ import static android.net.ConnectivityManager.TYPE_ETHERNET;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||
import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
|
||||
|
||||
import static com.android.internal.R.array.config_mobile_hotspot_provision_app;
|
||||
import static com.android.internal.R.array.config_tether_bluetooth_regexs;
|
||||
import static com.android.internal.R.array.config_tether_dhcp_range;
|
||||
@@ -30,15 +32,16 @@ import static com.android.internal.R.array.config_tether_wifi_regexs;
|
||||
import static com.android.internal.R.bool.config_tether_upstream_automatic;
|
||||
import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.util.SharedLog;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -68,12 +71,13 @@ public class TetheringConfiguration {
|
||||
public static final int DUN_REQUIRED = 1;
|
||||
public static final int DUN_UNSPECIFIED = 2;
|
||||
|
||||
// Default ranges used for the legacy DHCP server.
|
||||
// USB is 192.168.42.1 and 255.255.255.0
|
||||
// Wifi is 192.168.43.1 and 255.255.255.0
|
||||
// BT is limited to max default of 5 connections. 192.168.44.1 to 192.168.48.1
|
||||
// with 255.255.255.0
|
||||
// P2P is 192.168.49.1 and 255.255.255.0
|
||||
private static final String[] DHCP_DEFAULT_RANGE = {
|
||||
private static final String[] LEGACY_DHCP_DEFAULT_RANGE = {
|
||||
"192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254",
|
||||
"192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254",
|
||||
"192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254",
|
||||
@@ -89,8 +93,9 @@ public class TetheringConfiguration {
|
||||
public final boolean isDunRequired;
|
||||
public final boolean chooseUpstreamAutomatically;
|
||||
public final Collection<Integer> preferredUpstreamIfaceTypes;
|
||||
public final String[] dhcpRanges;
|
||||
public final String[] legacyDhcpRanges;
|
||||
public final String[] defaultIPv4DNS;
|
||||
public final boolean enableLegacyDhcpServer;
|
||||
|
||||
public final String[] provisioningApp;
|
||||
public final String provisioningAppNoUi;
|
||||
@@ -112,8 +117,9 @@ public class TetheringConfiguration {
|
||||
preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(ctx, dunCheck);
|
||||
isDunRequired = preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN);
|
||||
|
||||
dhcpRanges = getDhcpRanges(ctx);
|
||||
legacyDhcpRanges = getLegacyDhcpRanges(ctx);
|
||||
defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
|
||||
enableLegacyDhcpServer = getEnableLegacyDhcpServer(ctx);
|
||||
|
||||
provisioningApp = getResourceStringArray(ctx, config_mobile_hotspot_provision_app);
|
||||
provisioningAppNoUi = getProvisioningAppNoUi(ctx);
|
||||
@@ -150,7 +156,7 @@ public class TetheringConfiguration {
|
||||
dumpStringArray(pw, "preferredUpstreamIfaceTypes",
|
||||
preferredUpstreamNames(preferredUpstreamIfaceTypes));
|
||||
|
||||
dumpStringArray(pw, "dhcpRanges", dhcpRanges);
|
||||
dumpStringArray(pw, "legacyDhcpRanges", legacyDhcpRanges);
|
||||
dumpStringArray(pw, "defaultIPv4DNS", defaultIPv4DNS);
|
||||
|
||||
dumpStringArray(pw, "provisioningApp", provisioningApp);
|
||||
@@ -276,12 +282,12 @@ public class TetheringConfiguration {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String[] getDhcpRanges(Context ctx) {
|
||||
private static String[] getLegacyDhcpRanges(Context ctx) {
|
||||
final String[] fromResource = getResourceStringArray(ctx, config_tether_dhcp_range);
|
||||
if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) {
|
||||
return fromResource;
|
||||
}
|
||||
return copy(DHCP_DEFAULT_RANGE);
|
||||
return copy(LEGACY_DHCP_DEFAULT_RANGE);
|
||||
}
|
||||
|
||||
private static String getProvisioningAppNoUi(Context ctx) {
|
||||
@@ -309,6 +315,13 @@ public class TetheringConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean getEnableLegacyDhcpServer(Context ctx) {
|
||||
// TODO: make the default false (0) and update javadoc in Settings.java
|
||||
final ContentResolver cr = ctx.getContentResolver();
|
||||
final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
|
||||
return intVal != 0;
|
||||
}
|
||||
|
||||
private static String[] copy(String[] strarray) {
|
||||
return Arrays.copyOf(strarray, strarray.length);
|
||||
}
|
||||
|
||||
@@ -19,11 +19,14 @@ package com.android.server.connectivity.tethering;
|
||||
import android.content.Context;
|
||||
import android.net.INetd;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.dhcp.DhcpServer;
|
||||
import android.net.dhcp.DhcpServingParams;
|
||||
import android.net.ip.RouterAdvertisementDaemon;
|
||||
import android.net.util.InterfaceParams;
|
||||
import android.net.util.NetdService;
|
||||
import android.os.Handler;
|
||||
import android.net.util.SharedLog;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.android.internal.util.StateMachine;
|
||||
|
||||
@@ -69,4 +72,9 @@ public class TetheringDependencies {
|
||||
public NetworkRequest getDefaultNetworkRequest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface, DhcpServingParams params,
|
||||
SharedLog log) {
|
||||
return new DhcpServer(looper, iface, params, log);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.connectivity.tethering;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
@@ -23,7 +24,9 @@ import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -40,9 +43,15 @@ import static com.android.server.connectivity.tethering.IControlsTethering.STATE
|
||||
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.InterfaceConfiguration;
|
||||
import android.net.IpPrefix;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.MacAddress;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.dhcp.DhcpServer;
|
||||
import android.net.dhcp.DhcpServingParams;
|
||||
import android.net.ip.RouterAdvertisementDaemon;
|
||||
import android.net.util.InterfaceParams;
|
||||
import android.net.util.InterfaceSet;
|
||||
import android.net.util.SharedLog;
|
||||
import android.os.INetworkManagementService;
|
||||
@@ -58,6 +67,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
@@ -68,33 +78,58 @@ public class TetherInterfaceStateMachineTest {
|
||||
private static final String IFACE_NAME = "testnet1";
|
||||
private static final String UPSTREAM_IFACE = "upstream0";
|
||||
private static final String UPSTREAM_IFACE2 = "upstream1";
|
||||
private static final int DHCP_LEASE_TIME_SECS = 3600;
|
||||
|
||||
private static final InterfaceParams TEST_IFACE_PARAMS = new InterfaceParams(
|
||||
IFACE_NAME, 42 /* index */, MacAddress.ALL_ZEROS_ADDRESS, 1500 /* defaultMtu */);
|
||||
|
||||
@Mock private INetworkManagementService mNMService;
|
||||
@Mock private INetworkStatsService mStatsService;
|
||||
@Mock private IControlsTethering mTetherHelper;
|
||||
@Mock private InterfaceConfiguration mInterfaceConfiguration;
|
||||
@Mock private SharedLog mSharedLog;
|
||||
@Mock private DhcpServer mDhcpServer;
|
||||
@Mock private RouterAdvertisementDaemon mRaDaemon;
|
||||
@Mock private TetheringDependencies mTetheringDependencies;
|
||||
|
||||
@Captor private ArgumentCaptor<DhcpServingParams> mDhcpParamsCaptor;
|
||||
|
||||
private final TestLooper mLooper = new TestLooper();
|
||||
private final ArgumentCaptor<LinkProperties> mLinkPropertiesCaptor =
|
||||
ArgumentCaptor.forClass(LinkProperties.class);
|
||||
private TetherInterfaceStateMachine mTestedSm;
|
||||
|
||||
private void initStateMachine(int interfaceType) throws Exception {
|
||||
initStateMachine(interfaceType, false /* usingLegacyDhcp */);
|
||||
}
|
||||
|
||||
private void initStateMachine(int interfaceType, boolean usingLegacyDhcp) throws Exception {
|
||||
mTestedSm = new TetherInterfaceStateMachine(
|
||||
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog,
|
||||
mNMService, mStatsService, mTetherHelper, mTetheringDependencies);
|
||||
mNMService, mStatsService, mTetherHelper, usingLegacyDhcp,
|
||||
mTetheringDependencies);
|
||||
mTestedSm.start();
|
||||
// Starting the state machine always puts us in a consistent state and notifies
|
||||
// the rest of the world that we've changed from an unknown to available state.
|
||||
mLooper.dispatchAll();
|
||||
reset(mNMService, mStatsService, mTetherHelper);
|
||||
when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration);
|
||||
when(mTetheringDependencies.makeDhcpServer(
|
||||
any(), any(), mDhcpParamsCaptor.capture(), any())).thenReturn(mDhcpServer);
|
||||
when(mTetheringDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
|
||||
when(mTetheringDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
|
||||
|
||||
when(mRaDaemon.start()).thenReturn(true);
|
||||
}
|
||||
|
||||
private void initTetheredStateMachine(int interfaceType, String upstreamIface) throws Exception {
|
||||
initStateMachine(interfaceType);
|
||||
private void initTetheredStateMachine(int interfaceType, String upstreamIface)
|
||||
throws Exception {
|
||||
initTetheredStateMachine(interfaceType, upstreamIface, false);
|
||||
}
|
||||
|
||||
private void initTetheredStateMachine(int interfaceType, String upstreamIface,
|
||||
boolean usingLegacyDhcp) throws Exception {
|
||||
initStateMachine(interfaceType, usingLegacyDhcp);
|
||||
dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, STATE_TETHERED);
|
||||
if (upstreamIface != null) {
|
||||
dispatchTetherConnectionChanged(upstreamIface);
|
||||
@@ -112,7 +147,7 @@ public class TetherInterfaceStateMachineTest {
|
||||
public void startsOutAvailable() {
|
||||
mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(),
|
||||
TETHERING_BLUETOOTH, mSharedLog, mNMService, mStatsService, mTetherHelper,
|
||||
mTetheringDependencies);
|
||||
false /* usingLegacyDhcp */, mTetheringDependencies);
|
||||
mTestedSm.start();
|
||||
mLooper.dispatchAll();
|
||||
verify(mTetherHelper).updateInterfaceState(
|
||||
@@ -345,6 +380,45 @@ public class TetherInterfaceStateMachineTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startsDhcpServer() throws Exception {
|
||||
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
|
||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
||||
|
||||
assertDhcpStarted(new IpPrefix("192.168.43.0/24"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startsDhcpServerOnBluetooth() throws Exception {
|
||||
initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
|
||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
||||
|
||||
assertDhcpStarted(new IpPrefix("192.168.44.0/24"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotStartDhcpServerIfDisabled() throws Exception {
|
||||
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, true /* usingLegacyDhcp */);
|
||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
||||
|
||||
verify(mTetheringDependencies, never()).makeDhcpServer(any(), any(), any(), any());
|
||||
}
|
||||
|
||||
private void assertDhcpStarted(IpPrefix expectedPrefix) {
|
||||
verify(mTetheringDependencies, times(1)).makeDhcpServer(
|
||||
eq(mLooper.getLooper()), eq(TEST_IFACE_PARAMS), any(), eq(mSharedLog));
|
||||
verify(mDhcpServer, times(1)).start();
|
||||
final DhcpServingParams params = mDhcpParamsCaptor.getValue();
|
||||
// Last address byte is random
|
||||
assertTrue(expectedPrefix.contains(params.serverAddr.getAddress()));
|
||||
assertEquals(expectedPrefix.getPrefixLength(), params.serverAddr.getPrefixLength());
|
||||
assertEquals(1, params.defaultRouters.size());
|
||||
assertEquals(params.serverAddr.getAddress(), params.defaultRouters.iterator().next());
|
||||
assertEquals(1, params.dnsServers.size());
|
||||
assertEquals(params.serverAddr.getAddress(), params.dnsServers.iterator().next());
|
||||
assertEquals(DHCP_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command to the state machine under test, and run the event loop to idle.
|
||||
*
|
||||
|
||||
@@ -21,6 +21,8 @@ import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||
import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
|
||||
|
||||
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_NOT_REQUIRED;
|
||||
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_REQUIRED;
|
||||
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_UNSPECIFIED;
|
||||
@@ -29,15 +31,18 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.res.Resources;
|
||||
import android.net.util.SharedLog;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import com.android.internal.util.test.BroadcastInterceptingContext;
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
@@ -55,6 +60,7 @@ public class TetheringConfigurationTest {
|
||||
@Mock private Context mContext;
|
||||
@Mock private TelephonyManager mTelephonyManager;
|
||||
@Mock private Resources mResources;
|
||||
private MockContentResolver mContentResolver;
|
||||
private Context mMockContext;
|
||||
private boolean mHasTelephonyManager;
|
||||
|
||||
@@ -73,6 +79,11 @@ public class TetheringConfigurationTest {
|
||||
}
|
||||
return super.getSystemService(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentResolver getContentResolver() {
|
||||
return mContentResolver;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -86,6 +97,10 @@ public class TetheringConfigurationTest {
|
||||
.thenReturn(new String[]{ "test_wlan\\d" });
|
||||
when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs))
|
||||
.thenReturn(new String[0]);
|
||||
when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
|
||||
.thenReturn(new int[0]);
|
||||
mContentResolver = new MockContentResolver();
|
||||
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
|
||||
mMockContext = new MockContext(mContext);
|
||||
}
|
||||
|
||||
@@ -194,4 +209,29 @@ public class TetheringConfigurationTest {
|
||||
assertEquals(TYPE_MOBILE_HIPRI, upstreamIterator.next().intValue());
|
||||
assertFalse(upstreamIterator.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewDhcpServerDisabled() {
|
||||
Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
|
||||
|
||||
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
|
||||
assertTrue(cfg.enableLegacyDhcpServer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewDhcpServerEnabled() {
|
||||
Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
|
||||
|
||||
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
|
||||
assertFalse(cfg.enableLegacyDhcpServer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewDhcpServerDefault() {
|
||||
Settings.Global.putString(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, null);
|
||||
|
||||
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
|
||||
// TODO: change to false when new server is promoted to default
|
||||
assertTrue(cfg.enableLegacyDhcpServer);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user